home *** CD-ROM | disk | FTP | other *** search
/ ETO Development Tools 4 / ETO Development Tools 4.iso / Tools - Objects / MacApp / MacApp 3.0a2 / Libraries / UApplication.cp < prev    next >
Encoding:
Text File  |  1991-05-01  |  132.2 KB  |  4,891 lines  |  [TEXT/MPS ]

  1. // UApplication.cp 
  2. // Copyright Â© 1984-1991 by Apple Computer Inc. All rights reserved.
  3.  
  4. #ifndef __UAPPLICATION__
  5. #include <UApplication.h>
  6. #endif
  7.  
  8. #ifndef __STDIO__
  9. #include <StdIo.h>
  10. #endif
  11.  
  12. #ifndef __UGEOMETRY__
  13. #include <UGeometry.h>
  14. #endif
  15.  
  16. #ifndef __UBEHAVIOR__
  17. #include <UBehavior.h>
  18. #endif
  19.  
  20. #ifndef __UFILE__
  21. #include <UFile.h>
  22. #endif
  23.  
  24. #ifndef __UAPPLEEVENTS__
  25. #include <UAppleEvents.h>
  26. #endif
  27.  
  28. #ifndef __UPRINTHANDLER__
  29. #include <UPrintHandler.h>
  30. #endif
  31.  
  32. #ifndef __UWINDOW__
  33. #include <UWindow.h>
  34. #endif
  35.  
  36. #ifndef __USCROLLER__
  37. #include <UScroller.h>
  38. #endif
  39.  
  40. #ifndef __UFILEBASEDDOCUMENT__
  41. #include <UFileBasedDocument.h>
  42. #endif
  43.  
  44. #ifndef __UMACAPPUTILITIES__
  45. #include <UMacAppUtilities.h>
  46. #endif
  47.  
  48. #ifndef __UERRORMGR__
  49. #include <UErrorMgr.h>
  50. #endif
  51.  
  52. #ifndef __UMEMORY__
  53. #include <UMemory.h>
  54. #endif
  55.  
  56. #ifndef __UMENUMGR__
  57. #include <UMenuMgr.h>
  58. #endif
  59.  
  60. #ifndef __UMACAPPGLOBALS__
  61. #include <UMacAppGlobals.h>
  62. #endif
  63.  
  64. #ifndef __ERRORS__
  65. #include <Errors.h>
  66. #endif
  67.  
  68. #ifndef __TOOLUTILS__
  69. #include <ToolUtils.h>
  70. #endif
  71.  
  72. #ifndef __UBUSYCURSOR__
  73. #include <UBusyCursor.h>
  74. #endif
  75.  
  76. #ifndef __UDEBUG__
  77. #include <UDebug.h>
  78. #endif
  79.  
  80. #ifndef __UINSPECTOR__
  81. #include <UInspector.h>
  82. #endif
  83.  
  84. #ifndef __UCLIPBOARDMGR__
  85. #include <UClipboardMgr.h>
  86. #endif
  87.  
  88. #ifndef __RESOURCES__
  89. #include <Resources.h>
  90. #endif
  91.  
  92. #ifndef __DESK__
  93. #include <Desk.h>
  94. #endif
  95.  
  96. #ifndef __PACKAGES__
  97. #include <Packages.h>
  98. #endif
  99.  
  100. #ifndef __SCRIPT__
  101. #include <Script.h>
  102. #endif
  103.  
  104. #ifndef __DISKINIT__
  105. #include <DiskInit.h>
  106. #endif
  107.  
  108. #ifndef __OSEVENTS__
  109. #include <OSEvents.h>
  110. #endif
  111.  
  112. #ifndef __ULOMEM__
  113. #include <ULoMem.h>
  114. #endif
  115.  
  116. #ifndef __STDLIB__
  117. #include <StdLib.h>
  118. #endif
  119.  
  120. #ifndef __UVIEWSERVER__
  121. #include <UViewServer.h>
  122. #endif
  123.  
  124. #ifndef __UTABBEHAVIORS__
  125. #include <UTabBehaviors.h>
  126. #endif
  127.  
  128. //--------------------------------------------------------------------------------------------------
  129. TApplication* gApplication = NULL;
  130. Boolean gInitialized = FALSE;
  131. AEAddressDesc gServerAddress;
  132.  
  133. //--------------------------------------------------------------------------------------------------
  134. #pragma segment MAViewRes
  135.  
  136. CDocumentIterator::CDocumentIterator(TApplication* itsApplication,
  137.                            ArrayIndex itsLowBound,
  138.                            ArrayIndex itsHighBound,
  139.                            Boolean itsForward) :
  140.     CObjectIterator(itsApplication ? itsApplication->fDocList : NULL, itsLowBound, itsHighBound, itsForward)
  141.  
  142. {
  143. }
  144.  
  145. //--------------------------------------------------------------------------------------------------
  146. #pragma segment MAViewRes
  147.  
  148. CDocumentIterator::CDocumentIterator(TApplication* itsApplication,
  149.                            Boolean itsForward) :
  150.     CObjectIterator(itsApplication ? itsApplication->fDocList : NULL, itsForward)
  151. {
  152. }
  153.  
  154. //--------------------------------------------------------------------------------------------------
  155. #pragma segment MAViewRes
  156.  
  157. CDocumentIterator::CDocumentIterator(TApplication* itsApplication) :
  158.     CObjectIterator(itsApplication ? itsApplication->fDocList : NULL)
  159. {
  160. }
  161.  
  162. //--------------------------------------------------------------------------------------------------
  163. #pragma segment MAViewRes
  164.  
  165. TDocument* CDocumentIterator::CurrentDocument(void)
  166. {
  167.     return (TDocument*)this->CurrentObject();
  168. }
  169.  
  170. //--------------------------------------------------------------------------------------------------
  171. #pragma segment MAViewRes
  172.  
  173. TDocument* CDocumentIterator::FirstDocument(void)
  174. {
  175.     return (TDocument*)this->FirstObject();
  176. }
  177.  
  178. //--------------------------------------------------------------------------------------------------
  179. #pragma segment MAViewRes
  180.  
  181. TDocument* CDocumentIterator::NextDocument(void)
  182. {
  183.     return (TDocument*)this->NextObject();
  184. }
  185.  
  186. //--------------------------------------------------------------------------------------------------
  187. #pragma segment MAApplicationRes
  188.  
  189. pascal short TEventList::Compare(TObject* item1,
  190.                                    TObject* item2)
  191. {
  192.     // We want higher priority events at the end of the queue so we can delete from the end of the list
  193.     // This will save us a block move in DeleteElementsAt.
  194.     if (((TEvent *)item1)->fPriority > ((TEvent *)item2)->fPriority)
  195.         return kItem1LessThanItem2;
  196.     else if (((TEvent *)item1)->fPriority < ((TEvent *)item2)->fPriority)
  197.         return kItem1GreaterThanItem2;
  198.     else
  199.         return kItem1EqualItem2;
  200. }
  201.  
  202. //--------------------------------------------------------------------------------------------------
  203. #pragma segment MAInit
  204.  
  205. pascal void TEventList::IEventList(void)
  206. {
  207.     this->ISortedList();
  208. }
  209.  
  210. //--------------------------------------------------------------------------------------------------
  211. #pragma segment MAApplicationRes
  212.  
  213. pascal void TEventList::Insert(TObject* item)    // override 
  214. {
  215.     Boolean oldObjectPerm;
  216.     ArrayIndex anEqualItem;
  217.     ArrayIndex lastEqualItem;
  218.     ArrayIndex i;
  219.  
  220.     // Guarantee that the insertion can take place 
  221.     oldObjectPerm = AllocateObjectsFromPerm(FALSE);
  222.  
  223.     // !!! the search alg. should support this.    Performance will degrade here for
  224.     // big queues (shouldn't happen often, but come back and fix the general case anyways)
  225.     anEqualItem = this->GetEqualItemNo(item);
  226.  
  227.     // If any equal items were found then find the _last_ equal item 
  228.     if (anEqualItem != kEmptyIndex)
  229.     {
  230.         lastEqualItem = anEqualItem;            // Tentative value 
  231.         for (i = (anEqualItem + 1); i <= this->GetSize(); ++i)// ??? what about kMaxArrayIndex? 
  232.             if (this->Compare(this->At(i), item) == kItem1EqualItem2)
  233.                 lastEqualItem = i;
  234.             else
  235.                 break;
  236.         // InsertBefore is not available to a sorted list
  237.         this->InsertElementsBefore(lastEqualItem + 1, (Ptr)item, 1);
  238.     }
  239.     else
  240.         inherited::Insert(item);
  241.  
  242.     AllocateObjectsFromPerm(oldObjectPerm);
  243. }
  244.  
  245. //--------------------------------------------------------------------------------------------------
  246. #pragma segment MAFields
  247.  
  248. pascal void TEventList::Fields(TObject* obj)    // override 
  249. {
  250.     obj->DoToField("TEventList", (Ptr)NULL, bClass);
  251.  
  252.     inherited::Fields(obj);
  253. }
  254.  
  255. //--------------------------------------------------------------------------------------------------
  256. #if qDebug
  257. #pragma segment MADebugger
  258.  
  259. pascal void TDebugCommand::DoIt(void)
  260. {
  261.     EnterMacAppDebugger();
  262. }
  263. #endif
  264.  
  265. //--------------------------------------------------------------------------------------------------
  266. #if qDebug
  267. #pragma segment MASelCommand
  268.  
  269. pascal void TDebugCommand::IDebugCommand(CmdNumber itsCmdNumber)
  270. {
  271.     this->INoChangesCommand(itsCmdNumber, NULL, NULL);
  272. }
  273. #endif
  274.  
  275. //--------------------------------------------------------------------------------------------------
  276. #if qDebug
  277. #pragma segment MAFields
  278.  
  279. pascal void TDebugCommand::Fields(TObject* obj)    // override 
  280. {
  281.     obj->DoToField("TDebugCommand", (Ptr)NULL, bClass);
  282.  
  283.     inherited::Fields(obj);
  284. }
  285. #endif
  286.  
  287. //--------------------------------------------------------------------------------------------------
  288. #if qInspector
  289. #pragma segment MAInspector
  290.  
  291. pascal void TInspectorCommand::DoIt(void)
  292. {
  293.     MakeInspectorWindow();
  294. }
  295. #endif
  296.  
  297. //--------------------------------------------------------------------------------------------------
  298. #if qInspector
  299. #pragma segment MASelCommand
  300.  
  301. pascal void TInspectorCommand::IInspectorCommand(CmdNumber itsCmdNumber)
  302. {
  303.     this->INoChangesCommand(itsCmdNumber, NULL, NULL);
  304. }
  305. #endif
  306.  
  307. //--------------------------------------------------------------------------------------------------
  308. #if qInspector
  309. #pragma segment MAFields
  310.  
  311. pascal void TInspectorCommand::Fields(TObject* obj)// override 
  312. {
  313.     obj->DoToField("TInspectorCommand", (Ptr)NULL, bClass);
  314.  
  315.     inherited::Fields(obj);
  316. }
  317. #endif
  318.  
  319. //--------------------------------------------------------------------------------------------------
  320. #pragma segment MAApplicationRes
  321.  
  322. pascal void TQuitCommand::DoIt(void)
  323. {
  324.     FailInfo fi;
  325.  
  326.     if (fi.Try())
  327.     {
  328.         gApplication->fAppDone = TRUE;
  329.         gApplication->Close();
  330.         fi.Success();
  331.     }
  332.     else    // Recover
  333.     {
  334.         gApplication->fAppDone = FALSE;
  335.         fi.ReSignal();
  336.     }
  337. }
  338.  
  339. //--------------------------------------------------------------------------------------------------
  340. #pragma segment MAInit
  341.  
  342. pascal void TQuitCommand::IQuitCommand(CmdNumber itsCmdNumber)
  343. {
  344.     this->INoChangesCommand(itsCmdNumber, NULL, NULL);
  345. }
  346.  
  347. //--------------------------------------------------------------------------------------------------
  348. #pragma segment MAFields
  349.  
  350. pascal void TQuitCommand::Fields(TObject* obj)    // override 
  351. {
  352.     obj->DoToField("TQuitCommand", (Ptr)NULL, bClass);
  353.  
  354.     inherited::Fields(obj);
  355. }
  356.  
  357. //--------------------------------------------------------------------------------------------------
  358. #pragma segment MAApplicationRes
  359.  
  360. pascal void TUndoRedoCommand::DoIt(void)
  361. {
  362.     TCommand * lastCommand;
  363.  
  364.     lastCommand = gApplication->GetTarget()->GetLastCommand();
  365.     if (lastCommand->fChangesClipboard)
  366.         gClipboardMgr->SwapClipViews();
  367.  
  368.     if (lastCommand->fCmdDone)
  369.         lastCommand->UndoIt();
  370.     else
  371.         lastCommand->RedoIt();
  372.  
  373.     lastCommand->fCmdDone =!lastCommand->fCmdDone;
  374.  
  375.     if (lastCommand->fCausesChange)                // put this after .UndoIt/.RedoIt, so they
  376.                                                 // can change the flag
  377.         if (lastCommand->fChangedObject)
  378.             // Notify the proper object that a change has occurred
  379.             lastCommand->fChangedObject->Changed(lastCommand->GetChangeID(), lastCommand);
  380. }
  381.  
  382. //--------------------------------------------------------------------------------------------------
  383. #pragma segment MAInit
  384.  
  385. pascal void TUndoRedoCommand::IUndoRedoCommand(CmdNumber itsCmdNumber)
  386. {
  387.     this->INoChangesCommand(itsCmdNumber, NULL, NULL);
  388. }
  389.  
  390. //--------------------------------------------------------------------------------------------------
  391. #pragma segment MAFields
  392.  
  393. pascal void TUndoRedoCommand::Fields(TObject* obj)// override 
  394. {
  395.     obj->DoToField("TUndoRedoCommand", (Ptr)NULL, bClass);
  396.  
  397.     inherited::Fields(obj);
  398. }
  399.  
  400. //--------------------------------------------------------------------------------------------------
  401. #pragma segment MAOpen
  402.  
  403. pascal void TNewDocCommand::DoIt(void)
  404. {
  405.     gApplication->OpenNew(fID);
  406. }
  407.  
  408. //--------------------------------------------------------------------------------------------------
  409. #pragma segment MASelCommand
  410.  
  411. pascal void TNewDocCommand::INewDocCommand(CmdNumber itsCmdNumber)
  412. {
  413.     this->INoChangesCommand(itsCmdNumber, NULL, NULL);
  414. }
  415.  
  416. //--------------------------------------------------------------------------------------------------
  417. #pragma segment MAFields
  418.  
  419. pascal void TNewDocCommand::Fields(TObject* obj)// override 
  420. {
  421.     obj->DoToField("TNewDocCommand", (Ptr)NULL, bClass);
  422.  
  423.     inherited::Fields(obj);
  424. }
  425.  
  426. //--------------------------------------------------------------------------------------------------
  427. #pragma segment MASelCommand
  428.  
  429. pascal void TFilesCommand::IFilesCommand(CmdNumber itsCmdNumber,
  430.                                        TList* theDocuments)
  431. {
  432.     this->IAppleCommand(itsCmdNumber, NULL, NULL);
  433.     fFileList = theDocuments;
  434. }
  435.  
  436. //--------------------------------------------------------------------------------------------------
  437. #pragma segment MASelCommand
  438.  
  439. pascal void TFilesCommand::InitFromAppleEvent(CmdNumber itsCmdNumber,
  440.                                              TDocument* itsDocument,
  441.                                              TView* itsView,
  442.                                              const AppleEvent& itsMessage,
  443.                                              const AppleEvent& itsReply)// override 
  444. {
  445.     THandleList * aHandleList = NULL;
  446.     TList * aFileList = NULL;
  447.     FailInfo fi;
  448.  
  449.     VOLATILE(aHandleList);
  450.     VOLATILE(aFileList);
  451.  
  452.     inherited::InitFromAppleEvent(itsCmdNumber, itsDocument, itsView, itsMessage, itsReply);
  453.  
  454.     if (fi.Try())
  455.     {
  456.         aHandleList = new THandleList;
  457.         aHandleList->IHandleList();
  458.  
  459.         aFileList = NewList();
  460.         
  461.         fMessage->ReadHandleList(keyDirectObject, typeAlias, aHandleList);
  462.         
  463.         // Block is necessary for correct failure handling
  464.         {
  465.             CHandleIterator iter(aHandleList);
  466.             
  467.             for (Handle item = iter.FirstHandle(); iter.More(); item = iter.NextHandle())
  468.             {
  469.                 TFile * aFile;
  470.             
  471.                 aFile = gApplication->DoMakeFile(itsCmdNumber);
  472.                 FailOSErr(aFile->IdentifyByAlias(AliasHandle(item)));
  473.                 aFileList->InsertLast(aFile);
  474.                 item = DisposeIfHandle(item);
  475.             }
  476.         }
  477.         fi.Success();
  478.     }
  479.     else    // Recover
  480.     {
  481.         aHandleList = (THandleList *)(FreeIfObject(aHandleList));
  482.         aFileList = (TList *)(FreeIfObject(aFileList));
  483.  
  484.         fi.ReSignal();
  485.     }
  486.  
  487.     aHandleList->Free();                        // It is just a list of disposed handles…
  488.  
  489.     fFileList = aFileList;
  490. }
  491.  
  492. //--------------------------------------------------------------------------------------------------
  493. #pragma segment MASelCommand
  494.  
  495. pascal void TFilesCommand::Initialize(void)        // override 
  496. {
  497.     inherited::Initialize();
  498.  
  499.     fCausesChange = FALSE;
  500.     fFileList = NULL;
  501. }
  502.  
  503. //--------------------------------------------------------------------------------------------------
  504. #pragma segment MAClose
  505.  
  506. pascal void TFilesCommand::Free(void)            // override 
  507. {
  508.     fFileList = (TList *)(FreeIfObject(fFileList));
  509.  
  510.     inherited::Free();
  511. }
  512.  
  513. //--------------------------------------------------------------------------------------------------
  514. #pragma segment MAFields
  515.  
  516. pascal void TFilesCommand::Fields(TObject* obj)    // override 
  517. {
  518.     obj->DoToField("TFilesCommand", (Ptr)NULL, bClass);
  519.     obj->DoToField("fFileList", (Ptr) & fFileList, bObject);
  520.  
  521.     inherited::Fields(obj);
  522. }
  523.  
  524. //--------------------------------------------------------------------------------------------------
  525. #pragma segment MASelCommand
  526.  
  527. pascal void TODocCommand::IODocCommand(CmdNumber itsCmdNumber,
  528.                                        TList* theDocuments)
  529. {
  530.     this->IFilesCommand(itsCmdNumber, theDocuments);
  531. }
  532.  
  533. //--------------------------------------------------------------------------------------------------
  534. #pragma segment MAOpen
  535.  
  536. pascal void TODocCommand::DoIt(void)            // override 
  537. {
  538.     FailInfo fi;
  539.     
  540.     if (fi.Try())
  541.     {
  542.         {
  543.             CObjectIterator iter(fFileList);
  544.     
  545.             for (TFile* aFile = (TFile*)iter.FirstObject(); iter.More(); aFile = (TFile*)iter.NextObject())
  546.                 gApplication->OpenOld(fID, aFile);
  547.         }
  548.             
  549.         fi.Success();
  550.     }
  551.     else
  552.     {
  553.         this->ReportError(fi.error, fi.message);
  554.         fi.ReSignal();
  555.     }
  556. }
  557.  
  558. //--------------------------------------------------------------------------------------------------
  559. #pragma segment MAFields
  560.  
  561. pascal void TODocCommand::Fields(TObject* obj)    // override 
  562. {
  563.     obj->DoToField("TODocCommand", (Ptr)NULL, bClass);
  564.  
  565.     inherited::Fields(obj);
  566. }
  567.  
  568. //--------------------------------------------------------------------------------------------------
  569. #pragma segment MASelCommand
  570.  
  571. pascal void TPDocCommand::IPDocCommand(CmdNumber itsCmdNumber,
  572.                                        TList* theDocuments)
  573. {
  574.     this->IFilesCommand(itsCmdNumber, theDocuments);
  575. }
  576.  
  577. //--------------------------------------------------------------------------------------------------
  578. #pragma segment MAOpen
  579.  
  580. pascal void TPDocCommand::DoIt(void)            // override 
  581. {
  582.     FailInfo fi;
  583.     
  584.     if (fi.Try())
  585.     {
  586.         {
  587.             CObjectIterator iter(fFileList);
  588.     
  589.             for (TFile* aFile = (TFile*)iter.FirstObject(); iter.More(); aFile = (TFile*)iter.NextObject())
  590.                 if (!gApplication->PrintDocument(aFile))
  591.                     break;                            // guess we're done printing
  592.         }
  593.  
  594.         fi.Success();
  595.     }
  596.     else
  597.     {
  598.         this->ReportError(fi.error, fi.message);
  599.         fi.ReSignal();
  600.     }
  601. }
  602.  
  603. //--------------------------------------------------------------------------------------------------
  604. #pragma segment MAFields
  605.  
  606. pascal void TPDocCommand::Fields(TObject* obj)    // override 
  607. {
  608.     obj->DoToField("TPDocCommand", (Ptr)NULL, bClass);
  609.  
  610.     inherited::Fields(obj);
  611. }
  612.  
  613. //--------------------------------------------------------------------------------------------------
  614. #pragma segment MASelCommand
  615.  
  616. pascal void TAboutAppCommand::IAboutAppCommand(CmdNumber itsCmdNumber)
  617. {
  618.     this->INoChangesCommand(itsCmdNumber, NULL, NULL);
  619. }
  620.  
  621. //--------------------------------------------------------------------------------------------------
  622. #pragma segment MAAboutApp
  623.  
  624. pascal void TAboutAppCommand::DoIt(void)
  625. {
  626.     gApplication->DoShowAboutApp();
  627. }
  628.  
  629. //--------------------------------------------------------------------------------------------------
  630. #pragma segment MAFields
  631.  
  632. pascal void TAboutAppCommand::Fields(TObject* obj)// override 
  633. {
  634.     obj->DoToField("TAboutAppCommand", (Ptr)NULL, bClass);
  635.  
  636.     inherited::Fields(obj);
  637. }
  638.  
  639. //--------------------------------------------------------------------------------------------------
  640. #pragma segment MASelCommand
  641.  
  642. pascal void TEventCommand::IEventCommand(CmdNumber itsCmdNumber)
  643. {
  644.     this->INoChangesCommand(itsCmdNumber, NULL, NULL);
  645.  
  646.     // Hang around 
  647.     fFreeOnCompletion = FALSE;
  648.     fRecurring = TRUE;
  649.  
  650.     // Let more important stuff happen first 
  651.     fPriority = kPriorityLow;
  652. }
  653.  
  654. //--------------------------------------------------------------------------------------------------
  655. #pragma segment MAApplicationRes
  656.  
  657. pascal void TEventCommand::DoIt(void)
  658. {
  659.     gApplication->PollToolboxEvent(gApplication->fAllowApplicationToSleep);
  660. }
  661.  
  662. //--------------------------------------------------------------------------------------------------
  663. #pragma segment MAFields
  664.  
  665. pascal void TEventCommand::Fields(TObject* obj)    // override 
  666. {
  667.     obj->DoToField("TEventCommand", (Ptr)NULL, bClass);
  668.  
  669.     inherited::Fields(obj);
  670. }
  671.  
  672. //--------------------------------------------------------------------------------------------------
  673. #pragma segment MAInit
  674.  
  675. pascal void TApplication::Initialize(void)        // override 
  676. {
  677.     inherited::Initialize();
  678.  
  679.     fAllowApplicationToSleep = TRUE;
  680.     fAlwaysTrackCursor = FALSE;
  681.     fAppDone = FALSE;
  682.     fApplicationPSN.highLongOfPSN = kNoProcess;
  683.     fApplicationPSN.lowLongOfPSN = kNoProcess;
  684.     fClickCount = 0;
  685.     fEventList = NULL;
  686.     fCursorRgn = NULL;
  687.     fDocList = NULL;
  688.     fEventLevel = 1;                            // Prevents UnloadAllSegs from getting called
  689.                                                 // if a modal dialogs is used befure starting
  690.                                                 // the main event loop
  691.     fFreeWindowList = NULL;
  692.     fHeadCohandler = NULL;
  693.     fHelpRgn = NULL;
  694.     fIdlePhase = idleEnd;
  695.     fInBackground = FALSE;                        // When we start an app, it's in foreground 
  696.     fLastClickPart = inDesk;
  697.     fLastCommand = NULL;
  698.     fLastMsePt = gZeroPt;
  699.     fLastUpTime = TickCount();
  700.     fLaunchWithNewDocument = TRUE;
  701.     fLowSpaceInterval = kLowSpaceInterval;
  702.     fMainEventMask = everyEvent;
  703.     fMBarDisplayed = kMBarDisplayed;
  704.     fMBarNotDisplayed = kMBarNotDisplayed;
  705.     fMBarHierarchical = kMBarHierarchical;
  706.     fNextSpaceMsg = TickCount();
  707.     fSleepRgn = NULL;
  708.     fSysWindowActive = FALSE;
  709.     fTarget = this;
  710.     fUndoCmd = cNoCommand;
  711.     fUndoState = kShowUndo;
  712.  
  713. }
  714.  
  715. //--------------------------------------------------------------------------------------------------
  716. #pragma segment MAInit
  717.  
  718. pascal void TApplication::IApplication(const OSType itsMainFileType)
  719. {
  720.     const Str255 kParamText1 = "^0";
  721.  
  722.     short i;
  723.     Str255 s;
  724.     TEventList * anEventList;
  725.     Str255 apName;
  726.     short apRefnum;
  727.     Handle apParam;
  728.     TEventCommand * aEventCommand = NULL;
  729.     TWindowTabber* aTabber = NULL;
  730.     MenuHandle aMenu;
  731.     ProcessSerialNumber aPSN;
  732.     OSErr err;
  733.  
  734.     gApplication = this;
  735.  
  736.     this->IEvtHandler(NULL);
  737.  
  738.     fSleepRgn = MakeNewRgn();
  739.     fCursorRgn = MakeNewRgn();
  740.     fHelpRgn = MakeNewRgn();
  741.  
  742.     if (qNeedsProcessMgr || gConfiguration.hasProcessMgr)
  743.     {
  744.         err = GetCurrentProcess(aPSN);
  745.         if (err == noErr)
  746.             fApplicationPSN = aPSN;
  747.     }
  748.  
  749. #if qInspector
  750.     MakeInspector();
  751.     AddObjectToInspector(this);
  752.     AddObjectToInspector(gNullPrintHandler);
  753.     AddObjectToInspector(gPrintHandler);
  754. #endif
  755.  
  756.     fFreeWindowList = NewList();
  757. #if qDebug
  758.     fFreeWindowList->SetEltType("TWindow");
  759. #endif
  760.  
  761.     fDocList = NewList();
  762. #if qDebug
  763.     fDocList->SetEltType("TDocument");
  764. #endif
  765.  
  766.     // Posted commands won't go anywhere until we create the queue 
  767.     anEventList = new TEventList;
  768.     anEventList->IEventList();
  769.     fEventList = anEventList;
  770. #if qDebug
  771.     fEventList->SetEltType("TEvent");
  772. #endif
  773.  
  774.     // Make the command that operates the main Event Loop 
  775.     aEventCommand = new TEventCommand;
  776.     aEventCommand->IEventCommand(cNoCommand);
  777.     this->PostCommand(aEventCommand);
  778.  
  779.     // Install the default tab  behavior 
  780.     aTabber = new TWindowTabber;
  781.     aTabber->ITabber(TRUE);
  782.     this->AddBehavior(aTabber);
  783.  
  784.     fMainFileType = itsMainFileType;
  785.  
  786.     // !!! Do a bunch of menu setup that really should be in the menu unit or something 
  787.  
  788.     AddMenuBar(fMBarNotDisplayed, FALSE);        // reads in and initializes these menus. 
  789.     ClearMenuBar();
  790.  
  791.     AddMenuBar(fMBarDisplayed, FALSE);
  792.     AddMenuBar(fMBarHierarchical, TRUE);
  793.  
  794.     // Process the Apple menu 
  795.     aMenu = MAGetMenu(mApple);
  796.     if (aMenu)
  797.         AddResMenu(aMenu, 'DRVR');
  798.  
  799.     // If the "About" item contains the paramtext keystring (^0) then substitute the
  800.     // Application's name
  801.     CmdToName(cAboutApp, s);
  802.     i = s.Pos(kParamText1);
  803.     if (i != 0)
  804.     {
  805.         GetAppParms(apName, apRefnum, apParam);
  806.         s.Delete(i, kParamText1.Length());
  807.         s.Insert(apName, i);
  808.         SetCmdName(cAboutApp, s);
  809.     }
  810.  
  811.     // Add the debugger menus 
  812.     if (qDebug || qInspector)
  813.     {
  814.         AddMenuBar(kMBarDebug, FALSE);
  815.         if (qDebug)
  816.         {
  817.             AddMenuBar(kMBarDebugHierarchical, TRUE);
  818.             aMenu = MAGetMenu(mDebugFont);
  819.             if (aMenu)
  820.                 AddResMenu(aMenu, 'FONT');
  821.         }
  822.     }
  823.  
  824.     InvalidateMenuBar();
  825.  
  826.     this->DoMakeViewServer();                    // creates the view server
  827.  
  828.     // Finally finish up with the debugger;
  829. #if qDebug
  830.     InitUDebugAfterIApplication();
  831. #endif
  832.  
  833. }
  834.  
  835. //--------------------------------------------------------------------------------------------------
  836. #pragma segment MAActivate
  837.  
  838. pascal void TApplication::AboutToLoseControl(Boolean convertClipboard)
  839. {
  840.     CWMgrIterator iter;
  841.     
  842.     this->ActivateBusyCursor(FALSE);            // Don't want busy cursor while in desk acc.
  843.  
  844.     gClipboardMgr->AboutToLoseControl(convertClipboard);
  845.  
  846.     // Let all windows know that we're losing control - e.g. so floaters can hide themselves 
  847.     for (WindowPtr aWinPtr = iter.FirstWMgrWindow(); iter.More(); aWinPtr = iter.NextWMgrWindow())
  848.     {
  849.         TWindow* aWindow = this->WMgrToWindow(aWinPtr);
  850.         if (aWindow)
  851.             aWindow->AboutToLoseControl();
  852.     }
  853. }
  854.  
  855.  
  856. //--------------------------------------------------------------------------------------------------
  857. #pragma segment MAApplicationRes
  858.  
  859. pascal void TApplication::ActivateBusyCursor(Boolean entering)
  860. {
  861.     if (gBusyCursor)
  862.         gBusyCursor->Activate(entering);
  863. }
  864.  
  865. //--------------------------------------------------------------------------------------------------
  866. #pragma segment MAOpen
  867.  
  868. pascal void TApplication::AddDocument(TDocument* aNewDocument)
  869. {
  870.     if (fDocList)
  871.         fDocList->Insert(aNewDocument);
  872. }
  873.  
  874. //--------------------------------------------------------------------------------------------------
  875. #pragma segment MAOpen
  876.  
  877. pascal void TApplication::AddFreeWindow(TWindow* aWindow)
  878. {
  879.     if (fFreeWindowList)
  880.         fFreeWindowList->Insert(aWindow);
  881. }
  882.  
  883. //--------------------------------------------------------------------------------------------------
  884. #pragma segment MAGlobalsRes
  885. // Don't require a segment load for this 
  886.  
  887. // AlertFilter is a default filterProc used by MacAppAlert if the filterProc passed in is NULL.
  888. // It maps key strokes to the first character of button item titles.  It also hands off activate
  889. // and update processing to gApplication if we're not being called from an error condition or
  890. // while nested.
  891.  
  892. pascal Boolean TApplication::AlertFilter(DialogPtr theDialog,
  893.                                          EventRecord& theEvent,
  894.                                          short& itemHit)
  895.  
  896. {
  897.     static Str31 bufferString;                    // Must be a global, since it's used each time the
  898.                                                 // alert filter is entered. (It could be a field
  899.                                                 // of TApplication...)
  900.                                                 // If any script has a character with more than 31
  901.                                                 // bytes then the creatures that speak that language
  902.                                                 // have too many fingers!
  903.  
  904.     char theChar;
  905.     Rect box;
  906.     short byteType;
  907.     FailInfo fi;
  908.     Boolean oldInFilterState = gInFilter;
  909.     EventRecord anEvent;
  910.     TToolboxEvent * event;
  911.     Boolean returnValue = FALSE;
  912.  
  913.     VOLATILE(oldInFilterState);
  914.     VOLATILE(returnValue);
  915.  
  916.     gInFilter = TRUE;
  917.  
  918.     if (fi.Try())
  919.     {
  920.         // Wouldn't want MacApp to get lied to about where the focus _Actually_ is 
  921.         if (!gInhibitNestedHandling &&!oldInFilterState)
  922.             this->InvalidateFocus();
  923.  
  924.         switch (theEvent.what)
  925.         {
  926.             // this is the first event the alert gets, use it to initialize the global buffer
  927.             case activateEvt:                    
  928.                 if (((DialogPtr) theEvent.message) == theDialog)
  929.                     bufferString = "";         // initialize bufferString
  930.                 else
  931.                     if (!gInhibitNestedHandling && !oldInFilterState)
  932.                     {
  933.                         event = new TToolboxEvent;
  934.                         event->IToolboxEvent(this);
  935.                         event->HaveEvent(theEvent);
  936.                         event->Process(); //!!! this->DoEvent(cNoCommand, NULL, event);
  937.                     }
  938.                 break;
  939.  
  940.             // this is the first event the alert gets, so let's determine our VARs
  941.             case updateEvt:
  942.                 if (((DialogPtr) theEvent.message) != theDialog)
  943.                     if (!gInhibitNestedHandling &&!oldInFilterState)
  944.                     {
  945.                         event = new TToolboxEvent;
  946.                         event->IToolboxEvent(NULL);
  947.                         event->HaveEvent(theEvent);
  948.                         event->Process(); //!!! this->DoEvent(cNoCommand, NULL, event);
  949.                     }
  950.                 break;
  951.                 
  952.             // let's determine if the key pressed corresponds to our button titles
  953.             case keyDown:
  954.                 theChar = (unsigned char)(((theEvent.message) & charCodeMask));
  955.                 byteType = CharByte(&theChar, 0);
  956.  
  957.                 switch (byteType)
  958.                 {
  959.                     case smSingleByte:
  960.                         if ((theChar == chEnter) || (theChar == chReturn))
  961.                         {
  962.                             DoAlertKeyDown(theDialog, ok);
  963.                             itemHit = ok;
  964.                             returnValue = TRUE;
  965.                         }
  966.                         else if ((theChar == chEscape) || ((theChar == '.') && ((theEvent.modifiers & cmdKey) != 0)))
  967.                         {
  968.                             DoAlertKeyDown(theDialog, cancel);
  969.                             itemHit = cancel;
  970.                             returnValue = TRUE;
  971.                         }
  972.                         else
  973.                         {
  974.                             bufferString += theChar;
  975.                             if (CompareAlertKeysToItem(theDialog, bufferString, itemHit))
  976.                             {
  977.                                 DoAlertKeyDown(theDialog, itemHit);
  978.                                 returnValue = TRUE;
  979.                             }
  980.                         }
  981.                         break;
  982.                         
  983.                     case smFirstByte:
  984.                         bufferString += theChar;
  985.                         break;
  986.                         
  987.                     case smLastByte:
  988.                         bufferString += theChar;
  989.                         if (CompareAlertKeysToItem(theDialog, bufferString, itemHit))
  990.                         {
  991.                             DoAlertKeyDown(theDialog, itemHit);
  992.                             returnValue = TRUE;
  993.                         }
  994.                         break;
  995.                         
  996.                     case smMiddleByte:
  997.                         bufferString += theChar;
  998.                         break;
  999.                 }
  1000.         }
  1001.  
  1002.         // Idle but only if _REALLY_ necessary 
  1003.         if (!gInhibitNestedHandling &&!oldInFilterState &&!EventAvail(everyEvent, anEvent))
  1004.             this->Idle(fIdlePhase);
  1005.  
  1006.         fi.Success();
  1007.     }
  1008.     gInFilter = oldInFilterState;
  1009.  
  1010.     return returnValue;
  1011. }
  1012.  
  1013. //--------------------------------------------------------------------------------------------------
  1014. #pragma segment MAFile
  1015.  
  1016. pascal TDocument* TApplication::AlreadyOpen(TFile* aFile)
  1017. {
  1018.     CDocumentIterator iter(this);
  1019.     
  1020.     for (TDocument* aDocument = iter.FirstDocument(); iter.More(); aDocument = iter.NextDocument())
  1021.         if (aDocument->AlreadyOpen(aFile))
  1022.             return aDocument;
  1023.     return NULL;        // No document already open
  1024. }
  1025.  
  1026. //--------------------------------------------------------------------------------------------------
  1027. #pragma segment MAApplicationRes
  1028.  
  1029. pascal void TApplication::Beep(short duration)
  1030. {
  1031.     SysBeep(duration);
  1032. }
  1033.  
  1034. //--------------------------------------------------------------------------------------------------
  1035. #pragma segment MAFinder
  1036.  
  1037. // This is called only when opening/printing from the finder;
  1038. // it simulates the filtering done by Std File.
  1039.  
  1040. pascal Boolean CallFileFilterWithData(HParmBlkPtr paramBlock,
  1041.                                       Ptr myDataPtr,
  1042.                                       ProcPtr routine) = {
  1043.                                                           0x205F,// MOVEA.L (A7)+,A0 
  1044.                                                           0x4E90// JSR (A0) 
  1045.                                                           };
  1046.  
  1047. pascal Boolean CallFileFilter(HParmBlkPtr paramBlock,
  1048.                               ProcPtr routine) = {
  1049.                                                   0x205F,// MOVEA.L (A7)+,A0 
  1050.                                                   0x4E90// JSR (A0) 
  1051.                                                   };
  1052.  
  1053. pascal Boolean TApplication::CanOpenDocument(CmdNumber itsCmdNumber,
  1054.                                              TFile* aFile)
  1055. {
  1056.     short dlgID;
  1057.     Point where;
  1058.     ProcPtr fileFilter;
  1059.     ProcPtr dlgHook;
  1060.     ProcPtr modalFilter;
  1061.     ProcPtr activateProc;
  1062.     Ptr activeList;
  1063.     Ptr yourDataPtr = NULL;
  1064.     TypeListHandle typeList;
  1065.     HParamBlockRec paramBlock;
  1066.     short numTypes;
  1067.     Boolean returnValue = FALSE;
  1068.  
  1069.     // First check that file type is in the list of allowed file types. See SFGetParms
  1070.     // below for more info.
  1071.     typeList = (TypeListHandle)NewHandle(0);
  1072.     FailNIL(typeList);
  1073.  
  1074.     this->SFGetParms(itsCmdNumber, fileFilter, typeList, dlgID, where, dlgHook,
  1075.                         modalFilter, activeList, activateProc, yourDataPtr);
  1076.     numTypes = (short)(GetHandleSize((Handle)typeList) / sizeof(ResType));
  1077.     if (numTypes == 0)
  1078.     {
  1079.         if (!fileFilter)
  1080.             returnValue = TRUE;                // no file filter then want all types
  1081.         else if (aFile->GetFileInfo(paramBlock) == noErr)
  1082.         {
  1083.             if (qNeedsAliasMgr || gConfiguration.hasAliasMgr)
  1084.                 returnValue =!CallFileFilterWithData(¶mBlock, NULL, fileFilter);
  1085.             else
  1086.                 returnValue =!CallFileFilter(¶mBlock, fileFilter);
  1087.         }
  1088.         else
  1089.             returnValue = FALSE;
  1090.     }
  1091.     else
  1092.         for (short i = 1; i <= numTypes; ++i)    
  1093.             if (((long)(aFile->fFileType)) == ((long)(**typeList)[i]))
  1094.             {
  1095.                 if (!fileFilter)
  1096.                     returnValue = TRUE;
  1097.                 else if (aFile->GetFileInfo(paramBlock) == noErr)
  1098.                 {
  1099.                     if (qNeedsAliasMgr || gConfiguration.hasAliasMgr)
  1100.                         returnValue =!CallFileFilterWithData(¶mBlock, NULL, fileFilter);
  1101.                     else
  1102.                         returnValue =!CallFileFilter(¶mBlock, fileFilter);
  1103.                 }
  1104.                 else
  1105.                     returnValue = FALSE;
  1106.                 break;
  1107.             }
  1108.  
  1109.     typeList = (TypeListHandle)DisposeIfHandle((Handle)typeList);
  1110.     return returnValue;
  1111. }
  1112.  
  1113. //--------------------------------------------------------------------------------------------------
  1114. #pragma segment MAOpen
  1115.  
  1116. pascal Boolean TApplication::ChooseApplication(AEAddressDesc& theAddress)
  1117. {
  1118.     typedef TargetID* TargetIDPtr,
  1119.     ** TargetIDHandle;
  1120.  
  1121.     TargetIDHandle theTargetID;
  1122.     LocationNameRec theLoc;
  1123.     PortInfoRec thePortInfo;
  1124.     OSErr theErr;
  1125.     Str32 theLocNBPType;                        //!!!
  1126.     Boolean returnValue = FALSE;
  1127.  
  1128.     if (qNeedsAppleEventMgr || gConfiguration.hasAppleEventMgr)
  1129.     {
  1130.         theErr = PPCBrowser("", "", FALSE, theLoc, thePortInfo, NULL, "");
  1131.         if (theErr == noErr)
  1132.         {
  1133.             theTargetID = (TargetIDHandle)NewHandle(sizeof(TargetID));
  1134.             FailMemError();
  1135.             (*theTargetID)->location = theLoc;
  1136.             (*theTargetID)->name = thePortInfo.name;
  1137.             theAddress.descriptorType = typeTargetID;
  1138.             theAddress.dataHandle = (Handle)theTargetID;
  1139.             returnValue = TRUE;
  1140.         }
  1141.         else if (theErr != userCanceledErr)
  1142.             FailOSErr(theErr);
  1143.     }
  1144.     return returnValue;
  1145. }
  1146.  
  1147. //--------------------------------------------------------------------------------------------------
  1148. #pragma segment MAOpen
  1149.  
  1150. pascal Boolean TApplication::ChooseDocument(CmdNumber itsCmdNumber,
  1151.                                             TList** aFileList)
  1152. {
  1153.     typedef SFTypeList* SFTypeListPtr;
  1154.     typedef SFTypeListPtr* SFTypeListHandle;
  1155.  
  1156.     FailInfo fi;
  1157.     short dlgID;
  1158.     Point where;
  1159.     ProcPtr fileFilter;
  1160.     ProcPtr dlgHook;
  1161.     ProcPtr modalFilter;
  1162.     ProcPtr activateProc;
  1163.     Ptr activeList;
  1164.     Ptr yourDataPtr = NULL;
  1165.     TypeListHandle typeList;
  1166.     SFTypeListPtr pTypeList;
  1167.     short numTypes;
  1168.     StandardFileReply customReply;
  1169.     SFReply reply;
  1170.     TFile * aFile = NULL;
  1171.     Boolean fileChosen;
  1172.  
  1173.     VOLATILE(aFileList);
  1174.     VOLATILE(aFile);
  1175.  
  1176.     typeList = (TypeListHandle)NewHandle(0);
  1177.     FailNIL(typeList);
  1178.  
  1179.     this->SFGetParms(itsCmdNumber, fileFilter, typeList, dlgID, where, dlgHook,
  1180.                                     modalFilter, activeList, activateProc, yourDataPtr);
  1181.  
  1182.     numTypes = (short)(GetHandleSize((Handle) typeList) / sizeof(ResType));
  1183.  
  1184.     if (numTypes == 0)
  1185.     {
  1186.         numTypes = -1;                            // Tell Std File to display all types.
  1187.         pTypeList = (SFTypeListPtr) & pTypeList;// arbitrary, as long as it points to 4 bytes of valid memory
  1188.     }
  1189.     else
  1190.     {
  1191.         LockHandleHigh((Handle)typeList);        // in case Std File does allocations 
  1192.         pTypeList = *((SFTypeListHandle)typeList);
  1193.     }
  1194.  
  1195. #if qDebug
  1196.     // Causes TApplication.GetEvent to call CheckRsrcUsage. 
  1197.     gRsrcCheck = 0;
  1198. #endif
  1199.  
  1200.     this->UpdateAllWindows();                    // needed to work around bug in SF; if all
  1201.                                                 // windows are not updated you wont be able
  1202.                                                 // to mount a disk correctly.  ??? is this still true?
  1203.     if (fi.Try())
  1204.     {
  1205.  
  1206.         aFile = this->DoMakeFile(itsCmdNumber);
  1207.         fileChosen = FALSE;
  1208.  
  1209.         if (qNeedsAliasMgr || gConfiguration.hasAliasMgr)
  1210.         {
  1211.             CustomGetFile((FileFilterYDProcPtr)fileFilter, numTypes, (*pTypeList), customReply,
  1212.                             dlgID, where, (DlgHookYDProcPtr)dlgHook, (ModalFilterYDProcPtr)modalFilter,
  1213.                             (short*)activeList, (ActivateYDProcPtr)activateProc, yourDataPtr);
  1214.  
  1215.             fileChosen = customReply.sfGood;
  1216.             if (fileChosen)
  1217.             {
  1218.                 aFile->IdentifyWithScript(customReply.sfFile, customReply.sfScript);
  1219.                 aFile->fFileType = customReply.sfType;// Mouser needs the file type! 
  1220.             }
  1221.  
  1222.         }
  1223.         else
  1224.         {
  1225.             SFPGetFile(where, "", (FileFilterProcPtr)fileFilter, numTypes, (*pTypeList),
  1226.                         (DlgHookProcPtr)dlgHook, reply, dlgID, (ModalFilterProcPtr)modalFilter);
  1227.  
  1228.             fileChosen = reply.good;
  1229.             if (fileChosen)
  1230.             {
  1231.                 FailOSErr(aFile->IdentifyByTrio(reply.vRefNum, 0, reply.fName));
  1232.                 aFile->fFileType = reply.fType;    // Remember the file type 
  1233.             }
  1234.         }
  1235.         fi.Success();
  1236.     }
  1237.     else    // Recover
  1238.     {
  1239.         *aFileList = (TList *)FreeIfObject(*aFileList);
  1240.         aFile = (TFile *)FreeIfObject(aFile);
  1241.         fi.ReSignal();
  1242.     }
  1243.  
  1244.     typeList = (TypeListHandle)DisposeIfHandle((Handle)typeList);
  1245.  
  1246.     if (fileChosen)
  1247.     {
  1248.         // Return the file(s) chosen 
  1249.         *aFileList = NewList();
  1250.         (*aFileList)->InsertLast(aFile);        // !!! Eventually we need to return more than one file
  1251.     }
  1252.     else                                        // user cancelled or something 
  1253.         aFile = (TFile *)(FreeIfObject(aFile));    // free the unwanted file object 
  1254.     return fileChosen;
  1255. }
  1256.  
  1257. //--------------------------------------------------------------------------------------------------
  1258. #pragma segment MATerminate
  1259.  
  1260. pascal void TApplication::Close(void)
  1261. {
  1262.     // Close all of the visible non-floater windows 
  1263.     WindowPtr aWMgrWindow;
  1264.  
  1265.     while(aWMgrWindow = MAFrontWindow())
  1266.         this->CloseWMgrWindow(aWMgrWindow);
  1267.  
  1268.     // Close all of the windows 
  1269.     while(aWMgrWindow = FrontWindow())
  1270.         this->CloseWMgrWindow(aWMgrWindow);
  1271.  
  1272.     // Close any windowless documents.  Add a block for failure handling
  1273.     {
  1274.         CDocumentIterator iter(this);
  1275.         
  1276.         for (TDocument* aDocument = iter.FirstDocument(); iter.More(); aDocument = iter.NextDocument())
  1277.             aDocument->Close();
  1278.     }
  1279.  
  1280.     //??? gPrintHandler->Terminate();
  1281.     
  1282.     // Close down the cohandler chain.  Add a block for failure handling
  1283.     {
  1284.         CHandlerIterator iter(fHeadCohandler);
  1285.         
  1286.         for (TEvtHandler* aHandler = iter.FirstHandler(); iter.More(); aHandler = iter.NextHandler())
  1287.             FreeIfObject(aHandler);    // ??? also call Terminate ??? 
  1288.     }
  1289.  
  1290.     gClipboardMgr->Close();
  1291.  
  1292.     gViewServer->Free();                    // won't be creating any more views...
  1293. }
  1294.  
  1295. //--------------------------------------------------------------------------------------------------
  1296. #pragma segment MAClose
  1297.  
  1298. pascal void TApplication::CloseWMgrWindow(WindowPtr aWMgrWindow)
  1299. {
  1300.     TWindow * aWindow;
  1301.  
  1302.     if (qNeedsProcessMgr || gConfiguration.hasProcessMgr ||!IsDeskAccessory(aWMgrWindow))
  1303.     {
  1304.         aWindow = this->WMgrToWindow(aWMgrWindow);
  1305.         if (aWindow)
  1306.             aWindow->CloseByUser();
  1307.         else
  1308.             HideWindow(aWMgrWindow);
  1309.     }
  1310.     else
  1311.         CloseDeskAcc(((WindowPeek)aWMgrWindow)->windowKind);
  1312. }
  1313.  
  1314. //--------------------------------------------------------------------------------------------------
  1315. #pragma segment MAApplicationRes
  1316.  
  1317. pascal void TApplication::CommitLastCommand(void)
  1318. {
  1319.     gClipboardMgr->AbandonUndoClipboard();
  1320.  
  1321.     if (fLastCommand)
  1322.     {
  1323.         if (fLastCommand->fCmdDone)
  1324.             fLastCommand->Commit();
  1325.         if (fLastCommand->ShouldFreeOnCompletion())
  1326.             fLastCommand = (TCommand *)(FreeIfObject(fLastCommand));
  1327.     }
  1328. }
  1329.  
  1330. //--------------------------------------------------------------------------------------------------
  1331. #pragma segment MAApplicationRes
  1332.  
  1333. pascal short TApplication::CountClicks(TToolboxEvent* event,
  1334.                                        short whereMouseDown)
  1335. {
  1336.     short newClickCount;
  1337.  
  1338.     newClickCount = 1;
  1339.  
  1340.     if ((whereMouseDown == fLastClickPart) &&    // clicked in the same place… 
  1341.         (fClickCount > 0) &&                    // not the first click… 
  1342.         (event->fEventRecord.when - fLastUpTime < GetDblTime()) &&// close enough in time… 
  1343.         this->GetTarget()->DoMultiClick(fLastMsePt, event->fEventRecord.where))// close enough in space
  1344.         newClickCount = fClickCount + 1;
  1345.  
  1346.     fLastMsePt = event->fEventRecord.where;
  1347.  
  1348.     fLastClickPart = whereMouseDown;
  1349.     fClickCount = newClickCount;
  1350.     return newClickCount;
  1351. }
  1352.  
  1353. //--------------------------------------------------------------------------------------------------
  1354. #pragma segment MAClose
  1355.  
  1356. pascal void TApplication::DeleteDocument(TDocument* docToDelete)
  1357. {
  1358.     if (fDocList)
  1359.         fDocList->Delete(docToDelete);
  1360. }
  1361.  
  1362. //--------------------------------------------------------------------------------------------------
  1363. #pragma segment MAApplicationRes
  1364.  
  1365. pascal void TApplication::DeleteFreeWindow(TWindow* windowToDelete)
  1366. {
  1367.     if (fFreeWindowList)
  1368.         fFreeWindowList->Delete(windowToDelete);
  1369. }
  1370.  
  1371. //--------------------------------------------------------------------------------------------------
  1372. #pragma segment MAApplicationRes
  1373.  
  1374. pascal void TApplication::DispatchEvent(TEvent* event)
  1375. {
  1376.     TToolboxEvent * aToolboxEvent;
  1377.  
  1378.     //For Toolbox events, fID == fEventRecord.what 
  1379.     if ((event) && event->IsMemberClass(GetClassIDFromName("TToolboxEvent")))
  1380.     {
  1381.         aToolboxEvent = (TToolboxEvent *)event;
  1382.         switch (aToolboxEvent->fID)
  1383.         {
  1384.             case mouseUp:
  1385.                 this->HandleMouseUp(aToolboxEvent);
  1386.                 break;
  1387.  
  1388.             case mouseDown:
  1389.                 this->HandleMouseDown(aToolboxEvent);
  1390.                 break;
  1391.  
  1392.             case activateEvt:
  1393.                 this->HandleActivateEvent(aToolboxEvent);
  1394.                 break;
  1395.  
  1396.             case updateEvt:
  1397.                 this->HandleUpdateEvent(aToolboxEvent);
  1398.                 break;
  1399.  
  1400.             case keyDown:
  1401.             case autoKey:
  1402.                 this->HandleKeyDownEvent(aToolboxEvent);
  1403.                 break;
  1404.  
  1405.             case keyUp:
  1406.                 // !!! We'd like to have a chain for keyUp but a MultiFinder™ bug
  1407.                 // at least up to 6.0) keep us from reliably getting keyUp events
  1408.                 // after minor context switches (background updates, etc.).  It replaces
  1409.                 // the global event mask (which we would have had to change to get keyups
  1410.                 // in the first place) with the wrong mask.  Oh well, we had such good intentions!
  1411.                 break;
  1412.  
  1413.             case diskEvt:
  1414.                 this->HandleDiskEvent(aToolboxEvent);
  1415.                 break;
  1416.  
  1417.             case osEvt:
  1418.                 this->HandleSystemEvent(aToolboxEvent);
  1419.                 break;
  1420.  
  1421.             case nullEvent:
  1422.             case networkEvt:
  1423.             case driverEvt:
  1424.             case app1Evt:
  1425.             case app2Evt:
  1426.             case app3Evt:
  1427.                 this->HandleAlienEvent(event);
  1428.                 break;
  1429.  
  1430.             case kHighLevelEvent:
  1431.                 this->HandleHighLevelEvent(aToolboxEvent);
  1432.                 break;
  1433.  
  1434.             default:
  1435.                 this->HandleAlienEvent(event);
  1436.                 break;
  1437.         }
  1438.     }
  1439. }
  1440.  
  1441. //--------------------------------------------------------------------------------------------------
  1442. #pragma segment MAApplicationRes
  1443.  
  1444. pascal OSErr TApplication::DispatchAppleEvent(const AppleEvent& message,
  1445.                                               const AppleEvent& reply,
  1446.                                               long info)
  1447. {
  1448.     FailInfo fi;
  1449.     OSErr theErr = noErr;
  1450.     
  1451.     // Wrap this in a failure handler so that if some failure should occur (out of memory, etc.)
  1452.     // we are sure to inform the AppleEvent manager.  This will also inform the AppleEvent
  1453.     // manager if the event was not handled.  However, if the event is handled by posting a
  1454.     // command, any errors that occur while processing the command will be handled by a]
  1455.     // special failure handler in TAppleCommand::Process().
  1456.     if (fi.Try())
  1457.     {
  1458.         this->GetTarget()->HandleAppleCommand(info, message, reply);
  1459.         fi.Success();
  1460.     }
  1461.     else
  1462.         theErr = fi.error;
  1463.     return theErr;
  1464. }
  1465.  
  1466. //--------------------------------------------------------------------------------------------------
  1467. #pragma segment MAApplicationRes
  1468.  
  1469. pascal void TApplication::DoAppleCommand(CmdNumber aCmdNumber,
  1470.                                          const AppleEvent& message,
  1471.                                          const AppleEvent& reply)
  1472. {
  1473.     TODocCommand * anODocCommand = NULL;
  1474.     TPDocCommand * aPDocCommand = NULL;
  1475.  
  1476.     switch (aCmdNumber)
  1477.     {
  1478.         case cFinderNew:
  1479.             // Special case the old MacPaint™ style open if user knows about the option key.
  1480.             // !!! Probably should be changed to check the user interaction level first, though.
  1481.             if (IsOptionKeyDown())
  1482.                 this->HandleMenuCommand(cOpen);
  1483.             else if (fLaunchWithNewDocument)
  1484.                 this->GetTarget()->HandleMenuCommand(cFinderNew);
  1485.             break;
  1486.  
  1487.         case cFinderOpen:
  1488.             anODocCommand = new TODocCommand;
  1489.             anODocCommand->InitFromAppleEvent(aCmdNumber, NULL, NULL, message, reply);
  1490.             this->PostCommand(anODocCommand);
  1491.             break;
  1492.  
  1493.         case cFinderPrint:
  1494.             aPDocCommand = new TPDocCommand;
  1495.             aPDocCommand->InitFromAppleEvent(aCmdNumber, NULL, NULL, message, reply);
  1496.             this->PostCommand(aPDocCommand);
  1497.             break;
  1498.  
  1499.         case cFinderQuit:
  1500.             this->GetTarget()->HandleMenuCommand(cQuit);
  1501.             break;
  1502.  
  1503.         default:
  1504.             inherited::DoAppleCommand(aCmdNumber, message, reply);
  1505.             break;
  1506.     }
  1507. }
  1508.  
  1509. //--------------------------------------------------------------------------------------------------
  1510. #pragma segment MAApplicationRes
  1511.  
  1512. pascal void TApplication::DoCommandKey(TToolboxEvent* event)// override 
  1513. {
  1514.     if ((!event->fAutoKey) && (!InModalMenuState()))
  1515.     {
  1516.         this->SetupTheMenus();
  1517.         // If you want to have case sensitive command keys use the following line because
  1518.         // KeyEventToComponents returns the correct character for shifted keys when the command
  1519.         // key is down.  That lets us test for things like command-period correctly.  So… in order
  1520.         // to be backward compatible (sigh) we now have to ignore the _correct_ char that is passed
  1521.         // in (and is in event->fCharacter) and use the old ToolBox supplied unPasteurized character that
  1522.         // is left in the actual EventRecord
  1523.  
  1524.         // this->MenuEvent(MenuKey(event->fCharacter)); 
  1525.  
  1526.         this->MenuEvent(MenuKey((unsigned char)(((event->fEventRecord.message) & charCodeMask))));
  1527.     }
  1528. }
  1529.  
  1530. //--------------------------------------------------------------------------------------------------
  1531. #pragma segment MAApplicationRes
  1532.  
  1533. pascal void TApplication::DoKeyCommand(TToolboxEvent* event)// override 
  1534. {
  1535.     switch (event->fKeyCode)
  1536.     {
  1537.         case kF1VirtualCode:
  1538.             this->SetupTheMenus();
  1539.             if (CmdEnabled(cUndo))
  1540.                 this->GetTarget()->HandleMenuCommand(cUndo);
  1541.             break;
  1542.             
  1543.         case kF2VirtualCode:
  1544.             this->SetupTheMenus();
  1545.             if (CmdEnabled(cCut))
  1546.                 this->GetTarget()->HandleMenuCommand(cCut);
  1547.             break;
  1548.             
  1549.         case kF3VirtualCode:
  1550.             this->SetupTheMenus();
  1551.             if (CmdEnabled(cCopy))
  1552.                 this->GetTarget()->HandleMenuCommand(cCopy);
  1553.             break;
  1554.             
  1555.         case kF4VirtualCode:
  1556.             this->SetupTheMenus();
  1557.             if (CmdEnabled(cPaste))
  1558.                 this->GetTarget()->HandleMenuCommand(cPaste);
  1559.             break;
  1560.             
  1561.         case kClearVirtualCode:
  1562.             this->SetupTheMenus();
  1563.             if (CmdEnabled(cClear))
  1564.                 this->GetTarget()->HandleMenuCommand(cClear);
  1565.             break;
  1566.             
  1567.         default:
  1568.             inherited::DoKeyCommand(event);
  1569.             break;
  1570.     }
  1571. }
  1572.  
  1573. //--------------------------------------------------------------------------------------------------
  1574. #pragma segment MAOpen
  1575.  
  1576. pascal TDocument* TApplication::DoMakeDocument(CmdNumber,
  1577.                                                TFile* itsFile)
  1578. /* E X A M P L E
  1579.   {
  1580.   TDocument*        aYOURDocument;
  1581.   aYOURDocument = new TDocument;
  1582.   aYOURDocument->IYOURDocument();
  1583.   return aYOURDocument;
  1584.   }
  1585. */
  1586.  
  1587. {
  1588.     TFileBasedDocument * aDocument;
  1589.  
  1590.     // Allocate and initialize the document
  1591.     aDocument = NULL;
  1592.  
  1593.     if (qTemplateViews)
  1594.         aDocument = (TFileBasedDocument *)(NewStdObject(kStdDocument));
  1595.     else
  1596.         aDocument = new TFileBasedDocument;
  1597.  
  1598.     aDocument->IFileBasedDocument(itsFile, fMainFileType, '????', '????', kUsesDataFork, kUsesRsrcFork, !kDataOpen, !kRsrcOpen);
  1599.  
  1600.     return aDocument;
  1601. }
  1602.  
  1603. //--------------------------------------------------------------------------------------------------
  1604. #pragma segment MAOpen
  1605.  
  1606. pascal TFile* TApplication::DoMakeFile(CmdNumber)
  1607. {
  1608.     return NewFile();
  1609. }
  1610.  
  1611. //--------------------------------------------------------------------------------------------------
  1612. #pragma segment MASelCommand
  1613.  
  1614. pascal void TApplication::DoMenuCommand(CmdNumber aCmdNumber)
  1615. {
  1616.     FailInfo fi;
  1617.     TWindow * aWindow;
  1618.     TNewDocCommand * aNewDocCommand;
  1619.     TODocCommand * anODocCommand;
  1620.     TList * aFileList = NULL;
  1621.     TAboutAppCommand * aAboutAppCommand;
  1622.     TQuitCommand * aQuitCommand;
  1623.     TUndoRedoCommand * aUndoRedoCommand;
  1624.  
  1625.     Boolean oldObjectPerm;
  1626.  
  1627.     VOLATILE(aFileList);
  1628.  
  1629. #if qDebug
  1630.     TDebugCommand * aDebugCommand;
  1631.     Boolean oldState;
  1632. #endif
  1633.  
  1634. #if qInspector
  1635.     TInspectorCommand * aInspectorCommand;
  1636.     Boolean oldIState;
  1637. #endif
  1638.  
  1639.     /* ==================================================================================
  1640.       Some commands will be posted to perform actions that must _ALWAYS_ be available.
  1641.       The allocation cannot be allowed to fail.  So we do a temp allocation which by
  1642.       definition cannot be allowed to fail.  This strategy is used wherever we want to use
  1643.       command objects but don't want to leave the user twisting in the breeze.
  1644.       NOTE: Don't forget to allow for this memory in your mem! resource if you copy this
  1645.       style in your own code.
  1646.       ================================================================================== */
  1647.  
  1648.     aWindow = this->GetActiveWindow();
  1649.  
  1650.     switch (aCmdNumber)
  1651.     {
  1652.         case cQuit:
  1653.             oldObjectPerm = AllocateObjectsFromPerm(FALSE);
  1654.             aQuitCommand = new TQuitCommand;
  1655.             AllocateObjectsFromPerm(oldObjectPerm);
  1656.             aQuitCommand->IQuitCommand(aCmdNumber);
  1657.             this->PostCommand(aQuitCommand);
  1658.             break;
  1659.  
  1660.         case cNew:                                // cNew..cNewLast:
  1661.         case 11:
  1662.         case 12:
  1663.         case 13:
  1664.         case 14:
  1665.         case 15:
  1666.         case 16:
  1667.         case 17:
  1668.         case 18:
  1669.         case cNewLast:
  1670.         case cFinderNew:
  1671.             aNewDocCommand = new TNewDocCommand;
  1672.             aNewDocCommand->INewDocCommand(aCmdNumber);
  1673.             this->PostCommand(aNewDocCommand);
  1674.             break;
  1675.  
  1676.         case cOpen:                                // cOpen..cOpenLast:
  1677.         case 21:
  1678.         case 22:
  1679.         case 23:
  1680.         case 24:
  1681.         case 25:
  1682.         case 26:
  1683.         case 27:
  1684.         case 28:
  1685.         case cOpenLast:
  1686.             if (this->ChooseDocument(aCmdNumber, &aFileList))
  1687.             {
  1688.                 if (fi.Try())
  1689.                 {
  1690.                     anODocCommand = new TODocCommand;
  1691.                     anODocCommand->IODocCommand(aCmdNumber, aFileList);
  1692.                     fi.Success();
  1693.                 }
  1694.                 else    // Recover
  1695.                 {
  1696.                     aFileList = (TList *)(FreeIfObject(aFileList));
  1697.                     fi.ReSignal();
  1698.                 }
  1699.                 this->PostCommand(anODocCommand);
  1700.             }
  1701.             break;
  1702.  
  1703.         case cClose:
  1704.             if (qDebug && this->WMgrToWindow(FrontWindow()))
  1705.                 ProgramBreak("The frontmost window is a window object but didn''t handle the cClose CmdNumber, your TWindow subclass probably forgot to call inherited::DoMenuCommand!");
  1706.  
  1707.             this->CloseWMgrWindow(FrontWindow());    // TWindow would have handled the command
  1708.                                                       // before we get here so the window is
  1709.              break;                                    // probably a DA or something
  1710.  
  1711.         case cAboutApp:
  1712.             aAboutAppCommand = new TAboutAppCommand;
  1713.             aAboutAppCommand->IAboutAppCommand(aCmdNumber);
  1714.             this->PostCommand(aAboutAppCommand);
  1715.             break;
  1716.  
  1717. #if qDebug
  1718.         case cDebugWind:
  1719.             DebugShowTranscriptWindow();
  1720.             break;
  1721.             
  1722.         case cExperimenting:
  1723.             gExperimenting =!gExperimenting;
  1724.             break;
  1725.             
  1726.         case cReportEvt:
  1727.             gReportEvt =!gReportEvt;
  1728.             break;
  1729.             
  1730.         case cDebugPrinting:
  1731.             gDebugPrinting =!gDebugPrinting;
  1732.             break;
  1733.             
  1734.         case cReportMenuChoices:
  1735.             gReportMenuChoices =!gReportMenuChoices;
  1736.             break;
  1737.             
  1738.         case cIntenseDebugging:
  1739.             gIntenseDebugging =!gIntenseDebugging;
  1740.             break;
  1741.             
  1742.         case cRefreshFrontWindow:
  1743.             if (aWindow)
  1744.                 aWindow->ForceRedraw();
  1745.             break;
  1746.             
  1747.         case cModalToggle:
  1748.             if (aWindow)
  1749.                 aWindow->fIsModal =!aWindow->fIsModal;
  1750.             break;
  1751.             
  1752.         case cDoFirstClick:
  1753.             if (aWindow)
  1754.                 aWindow->fDoFirstClick =!aWindow->fDoFirstClick;
  1755.             break;
  1756.             
  1757.         case cSetSysJust:
  1758.             // swap the current setting 
  1759.             if (GetActualJustification(teFlushDefault) == teFlushLeft)
  1760.                 SetSysJust(teFlushRight);
  1761.             else
  1762.                 SetSysJust(teFlushLeft);
  1763.             break;
  1764.  
  1765.         case cEnterMacAppDebugger:
  1766.             oldObjectPerm = AllocateObjectsFromPerm(FALSE);
  1767.             oldState = AddNewObjectsToInspector(FALSE);
  1768.             aDebugCommand = new TDebugCommand;
  1769.             AddNewObjectsToInspector(oldState);
  1770.             AllocateObjectsFromPerm(oldObjectPerm);
  1771.  
  1772.             aDebugCommand->IDebugCommand(aCmdNumber);
  1773.             this->PostCommand(aDebugCommand);
  1774.             break;
  1775. #endif
  1776.  
  1777. #if qDebug
  1778.         case cTraceSetupMenus:
  1779.             gTraceSetupMenus =!gTraceSetupMenus;
  1780.             break;
  1781.             
  1782.         case cTraceIdle:
  1783.             gTraceIdle =!gTraceIdle;
  1784.             break;
  1785. #endif
  1786.  
  1787. #if qInspector
  1788.         case cNewInspectorWindow:
  1789.             oldIState = AddNewObjectsToInspector(FALSE);
  1790.             aInspectorCommand = new TInspectorCommand;
  1791.             AddNewObjectsToInspector(oldIState);
  1792.             aInspectorCommand->IInspectorCommand(aCmdNumber);
  1793.             this->PostCommand(aInspectorCommand);
  1794.             break;
  1795. #endif
  1796.  
  1797.         case cUndo:
  1798.             oldObjectPerm = AllocateObjectsFromPerm(FALSE);
  1799.             aUndoRedoCommand = new TUndoRedoCommand;
  1800.             AllocateObjectsFromPerm(oldObjectPerm);
  1801.  
  1802.             aUndoRedoCommand->IUndoRedoCommand(aCmdNumber);
  1803.             this->PostCommand(aUndoRedoCommand);
  1804.             break;
  1805.  
  1806.         default:
  1807.             inherited::DoMenuCommand(aCmdNumber);
  1808.             break;
  1809.     }
  1810. }
  1811.  
  1812. //--------------------------------------------------------------------------------------------------
  1813. #pragma segment MAApplicationRes
  1814.  
  1815. pascal void TApplication::DoSetupMenus(void)
  1816. {
  1817.     Boolean lowSpace;
  1818.     WindowPtr aWindowPtr;
  1819.  
  1820.     inherited::DoSetupMenus();
  1821.  
  1822.     lowSpace = MemSpaceIsLow();
  1823.  
  1824.     Enable(cAboutApp, TRUE);
  1825.  
  1826.     Enable(cQuit, fEventLevel <= 1);            // Can't enable Quit if in nested event handling
  1827.     Enable(cNew, !lowSpace);
  1828.     Enable(cOpen, !lowSpace);
  1829.  
  1830.     aWindowPtr = FrontWindow();
  1831.     if ((aWindowPtr) && (this->WMgrToWindow(aWindowPtr) == NULL))
  1832.         // window objects will take care of themselves, but we take care of the indigent.
  1833.         Enable(cClose, ((WindowPeek)aWindowPtr)->goAwayFlag != FALSE);
  1834. }
  1835.  
  1836. //--------------------------------------------------------------------------------------------------
  1837. #pragma segment MAAboutApp
  1838.  
  1839. Boolean hadCreditsStringList;                    // does the rsrc 'STR#' == kDefaultCredits exist ?
  1840. short lastCreditsStringIndex;                    // the last string in the STR# to be displayed
  1841. long lastCreditsShownTicks;                        // the tickcount when the last Credit was Shown
  1842. StringHandle originalText;                        // the about box's original text (prior to credits)
  1843. short waitTicks;                                // how long to wait between credits 
  1844.  
  1845. pascal Boolean DoShowAboutAppFilter(DialogPtr theDialog,
  1846.                                     EventRecord& theEvent,
  1847.                                     short& itemHit)
  1848. {
  1849.     Str255 s;
  1850.     Str255 originalStr;
  1851.     Handle item;
  1852.     Boolean returnValue = FALSE;
  1853.     short itemType;
  1854.     Rect box;
  1855.  
  1856.     switch (theEvent.what)
  1857.     {
  1858.         case keyDown:
  1859.             switch ((unsigned char)(((theEvent.message) & charCodeMask)))
  1860.             {
  1861.                 case chEnter:
  1862.                 case chReturn:
  1863.                     DoAlertKeyDown(theDialog, ok);
  1864.                     break;
  1865.             }
  1866.             break;
  1867.             
  1868.         case nullEvent:
  1869.             if ((TickCount() - lastCreditsShownTicks) > waitTicks)
  1870.             {
  1871.                 short itemNo = 1;
  1872.  
  1873.                 do
  1874.                 {
  1875.                     item = NULL;
  1876.                     GetDItem(theDialog, itemNo, itemType, item, box);
  1877.                     if (((itemType) & 0x7F) == statText)    // we don't care if its enabled or not 
  1878.                         break;
  1879.                     else
  1880.                         ++itemNo;
  1881.                 } while (item);
  1882.                 
  1883.                 GetIndString(s, kDefaultCredits, lastCreditsStringIndex);
  1884.                 
  1885.                 if (!s.IsEmpty())
  1886.                 {
  1887.                     // save the original text 
  1888.                     if ((lastCreditsStringIndex == 1) && ((*originalText)->IsEmpty() && item))
  1889.                     {
  1890.                         GetIText(item, originalStr);
  1891.                         SetString(originalText, originalStr);
  1892.                     }
  1893.                     ++lastCreditsStringIndex;
  1894.                     lastCreditsShownTicks = TickCount();
  1895.                     if (item)
  1896.                         SetIText(item, s);
  1897.                     waitTicks = (short)Min((s.Length() * 6), 60);
  1898.                 }
  1899.                 else                            // no more items 
  1900.                     {
  1901.                     lastCreditsStringIndex = 1;
  1902.                     lastCreditsShownTicks = TickCount();
  1903.                     if (item)
  1904.                     {
  1905.                         BlockMove(((Ptr) *originalText), (Ptr) & originalStr, (**originalText).Length() + 1);
  1906.                         SetIText(item, originalStr);
  1907.                     }
  1908.                     waitTicks = 6 * 60;
  1909.                 }
  1910.             }
  1911.             break;
  1912.     }                                            /* switch */
  1913.  
  1914.     // Forward on to the standard filter 
  1915.     if (gMacAppAlertFilter)
  1916.         returnValue = CallAlertFilter(theDialog, theEvent, itemHit, gMacAppAlertFilter);
  1917.  
  1918.     return returnValue;
  1919. }
  1920.  
  1921. //--------------------------------------------------------------------------------------------------
  1922. #pragma segment MAAboutApp
  1923.  
  1924. pascal void TApplication::DoShowAboutApp(void)
  1925. /* Method to display the "About" box for your application.  Override to do interesting things.
  1926.   Since it is normally called from a command; the app usually has the maximum free space available. */
  1927. {
  1928.     Str255 apName;
  1929.     short apRefnum;
  1930.     Handle apParam;
  1931.  
  1932.  
  1933.     FailSpaceIsLow();
  1934.     GetAppParms(apName, apRefnum, apParam);
  1935.     ParamText(apName, "", "", "");                // Put Application name in the about box 
  1936.     hadCreditsStringList = (GetResource('STR#', kDefaultCredits) != NULL);
  1937.     if (hadCreditsStringList)
  1938.     {
  1939.         lastCreditsStringIndex = 1;
  1940.         lastCreditsShownTicks = TickCount();
  1941.         waitTicks = 5 * 60;
  1942.         originalText = NewString("");
  1943.         MacAppAlert(phAboutApp, (ProcPtr) & DoShowAboutAppFilter);
  1944.         originalText = (StringHandle)DisposeIfHandle((Handle)originalText);
  1945.     }
  1946.     else
  1947.         StdAlert(phAboutApp);
  1948. }
  1949.  
  1950. //--------------------------------------------------------------------------------------------------
  1951. #pragma segment MAApplicationRes
  1952.  
  1953. pascal void TApplication::EachActiveWindow(DoToWindowType DoToWindow,
  1954.                                            void* staticLink)
  1955. {
  1956.     if ((qNeedsProcessMgr) || (gConfiguration.hasProcessMgr) || (!IsDeskAccessory(FrontWindow())))
  1957.     {
  1958.         CWMgrIterator iter;
  1959.         
  1960.         for (WindowPtr aWinPtr = iter.FirstWMgrWindow(); iter.More(); aWinPtr = iter.NextWMgrWindow())
  1961.         {
  1962.             TWindow* aWindow = this->WMgrToWindow(aWinPtr);
  1963.         
  1964.             if ((aWindow) && (aWindow->IsShown()) && (aWindow->IsActive()))
  1965.                 DoToWindow(aWindow, staticLink);
  1966.         }
  1967.     }
  1968. }
  1969.  
  1970. //--------------------------------------------------------------------------------------------------
  1971. #pragma segment MAApplicationRes
  1972.  
  1973. pascal void TApplication::EachFreeWindow(pascal void(* DoToWindow)(TWindow* aWindow,
  1974.                                                                    void* staticLink),
  1975.                                          void* staticLink)
  1976. {
  1977.     if (fFreeWindowList)
  1978.         fFreeWindowList->Each((DoToObjectType)DoToWindow, staticLink);
  1979. }
  1980.  
  1981. //--------------------------------------------------------------------------------------------------
  1982. #pragma segment MAFields
  1983.  
  1984. pascal void DoGlobalFields(TObject* obj)
  1985. {
  1986.     obj->DoToField("gApplication", &gApplication, bObject);
  1987.     obj->DoToField("gApplicationStyle", &gApplicationStyle, bTextStyle);
  1988.     obj->DoToField("gConfiguration", &gConfiguration, bConfigRec);
  1989.     obj->DoToField("gCouldPrint", &gCouldPrint, bBoolean);
  1990.     obj->DoToField("gCurrPrintHandler", &gCurrPrintHandler, bObject);
  1991.     obj->DoToField("gDrawingPictScrap", &gDrawingPictScrap, bBoolean);
  1992.     obj->DoToField("gDrawingPictScrapView", &gDrawingPictScrapView, bObject);
  1993.     obj->DoToField("gErrorParm3", &gErrorParm3, bString);
  1994.     obj->DoToField("gFocusedView", &gFocusedView, bObject);
  1995.     obj->DoToField("gInitialized", &gInitialized, bBoolean);
  1996.     obj->DoToField("gMenuBarIsInvalid", &gMenuBarIsInvalid, bBoolean);
  1997.     obj->DoToField("gMenusAreInvalid", &gMenusAreInvalid, bBoolean);
  1998.     obj->DoToField("gNullPrintHandler", &gNullPrintHandler, bObject);
  1999.     obj->DoToField("gNumUntitled", &gNumUntitled, bInteger);
  2000.     obj->DoToField("gOldChooserFlag", &gOldChooserFlag, bBoolean);
  2001.  
  2002.     obj->DoToField("gOrthogonal[hSel]", &gOrthogonal[hSel], bByte);
  2003.     obj->DoToField("gOrthogonal[vSel]", &gOrthogonal[vSel], bByte);
  2004.  
  2005.     obj->DoToField("gPageOffset", &gPageOffset, bVPoint);
  2006.     obj->DoToField("gPrintHandler", &gPrintHandler, bObject);
  2007.     obj->DoToField("gPrinting", &gPrinting, bBoolean);
  2008.     obj->DoToField("gStdHysteresis", &gStdHysteresis, bPoint);
  2009.     obj->DoToField("gStdStaggerCount", &gStdStaggerCount, bInteger);
  2010.     obj->DoToField("gStdWMoveBounds", &gStdWMoveBounds, bRect);
  2011.     obj->DoToField("gStdWScreenRect", &gStdWScreenRect, bRect);
  2012.     obj->DoToField("gStdWSizeRect", &gStdWSizeRect, bRect);
  2013.     obj->DoToField("gSystemStyle", &gSystemStyle, bTextStyle);
  2014.     obj->DoToField("gTempRgn", &gTempRgn, bRgnHandle);
  2015.     obj->DoToField("gWorkPort", &gWorkPort, bGrafPtr);
  2016.     obj->DoToField("gWResSignature", &gWResSignature, bIDType);
  2017.     obj->DoToField("gWResType", &gWResType, bString);
  2018.     obj->DoToField("gZeroPt", &gZeroPt, bPoint);
  2019.     obj->DoToField("gZeroRect", &gZeroRect, bRect);
  2020.     obj->DoToField("gZeroVPt", &gZeroVPt, bVPoint);
  2021.     obj->DoToField("gZeroVRect", &gZeroVRect, bVRect);
  2022.  
  2023. #if qDebug
  2024.     obj->DoToField("gBusyTempRgn", &gBusyTempRgn, bBoolean);
  2025.     obj->DoToField("gDebugPrinting", &gDebugPrinting, bBoolean);
  2026.     obj->DoToField("gExperimenting", &gExperimenting, bBoolean);
  2027.     obj->DoToField("gIntenseDebugging", &gIntenseDebugging, bBoolean);
  2028.     obj->DoToField("gReportEvt", &gReportEvt, bBoolean);
  2029.     obj->DoToField("gReportMenuChoices", &gReportMenuChoices, bBoolean);
  2030.     obj->DoToField("gRsrcCheck", &gRsrcCheck, bBoolean);
  2031.     obj->DoToField("gTraceIdle", &gTraceIdle, bBoolean);
  2032.     obj->DoToField("gUsedBy", &gUsedBy, bString);
  2033. #endif
  2034.  
  2035. }
  2036.  
  2037.  
  2038. pascal void TApplication::Fields(TObject* obj)    // override 
  2039. {
  2040.     obj->DoToField("TApplication", (Ptr)NULL, bClass);
  2041.     obj->DoToField("fAppDone", &fAppDone, bBoolean);
  2042.     obj->DoToField("fApplicationPSN.highLongOfPSN", &fApplicationPSN.highLongOfPSN, bLongInt);
  2043.     obj->DoToField("fApplicationPSN.lowLongOfPSN", &fApplicationPSN.lowLongOfPSN, bLongInt);
  2044.     obj->DoToField("fClickCount", &fClickCount, bInteger);
  2045.     obj->DoToField("fEventList", &fEventList, bObject);
  2046.     obj->DoToField("fCursorRgn", &fCursorRgn, bRgnHandle);
  2047.     obj->DoToField("fDocList", &fDocList, bObject);
  2048.     obj->DoToField("fEventLevel", &fEventLevel, bInteger);
  2049.     obj->DoToField("fFreeWindowList", &fFreeWindowList, bObject);
  2050.     obj->DoToField("fHeadCohandler", &fHeadCohandler, bObject);
  2051.     obj->DoToField("fHelpRgn", &fHelpRgn, bRgnHandle);
  2052.     obj->DoToField("fIdlePhase", &fIdlePhase, bByte);
  2053.     obj->DoToField("fInBackground", &fInBackground, bBoolean);
  2054.     obj->DoToField("fLastClickPart", &fLastClickPart, bInteger);
  2055.     obj->DoToField("fLastCommand", &fLastCommand, bObject);
  2056.     obj->DoToField("fLastMsePt", &fLastMsePt, bPoint);
  2057.     obj->DoToField("fLastUpTime", &fLastUpTime, bLongInt);
  2058.     obj->DoToField("fLaunchWithNewDocument", &fLaunchWithNewDocument, bBoolean);
  2059.     obj->DoToField("fLowSpaceInterval", &fLowSpaceInterval, bLongInt);
  2060.     obj->DoToField("fMainEventMask", &fMainEventMask, bHexInteger);
  2061.     obj->DoToField("fMainFileType", &fMainFileType, bOSType);
  2062.     obj->DoToField("fMBarDisplayed", &fMBarDisplayed, bInteger);
  2063.     obj->DoToField("fMBarHierarchical", &fMBarHierarchical, bInteger);
  2064.     obj->DoToField("fMBarNotDisplayed", &fMBarNotDisplayed, bInteger);
  2065.     obj->DoToField("fNextSpaceMsg", &fNextSpaceMsg, bLongInt);
  2066.     obj->DoToField("fSleepRgn", &fSleepRgn, bRgnHandle);
  2067.     obj->DoToField("fSysWindowActive", &fSysWindowActive, bBoolean);
  2068.     obj->DoToField("fTarget", &fTarget, bObject);
  2069.     obj->DoToField("fUndoCmd", &fUndoCmd, bInteger);
  2070.     obj->DoToField("fUndoState", &fUndoState, bBoolean);
  2071.  
  2072.     DoGlobalFields(obj);
  2073.  
  2074.     inherited::Fields(obj);
  2075. }
  2076.  
  2077. //--------------------------------------------------------------------------------------------------
  2078. #pragma segment MAApplicationRes
  2079.  
  2080. pascal void TApplication::ForAllDocumentsDo(pascal void(* DoToDoc)(TDocument* aDocument,
  2081.                                                                    void* staticLink),
  2082.                                             void* staticLink)
  2083. {
  2084.     if (fDocList)
  2085.         fDocList->Each((DoToObjectType)DoToDoc, staticLink);
  2086. }
  2087.  
  2088. //--------------------------------------------------------------------------------------------------
  2089. #pragma segment MAApplicationRes
  2090.  
  2091. pascal void TApplication::ForAllWindowsDo(DoToWindowType DoToWindow,
  2092.                                           void* staticLink)
  2093. {
  2094.     CDocumentIterator iter(this);
  2095.  
  2096.     for (TDocument* aDocument = iter.FirstDocument(); iter.More(); aDocument = iter.NextDocument())
  2097.             aDocument->ForAllWindowsDo(DoToWindow, staticLink);
  2098.     this->EachFreeWindow(DoToWindow, staticLink);
  2099. }
  2100.  
  2101. //--------------------------------------------------------------------------------------------------
  2102. #pragma segment MAApplicationRes
  2103.  
  2104. pascal void TApplication::ExcludeWindowRegions(RgnHandle deskTopRgn,
  2105.                                                TestWindowType TestWindow,
  2106.                                                void* staticLink)
  2107. {
  2108.     GrafPtr savedPort;
  2109.     CWMgrIterator iter;
  2110.  
  2111.     // Remove the visRgn of all windows for which TestWindow returns TRUE 
  2112.     GetPort(savedPort);
  2113.     for (WindowPtr aWinPtr = iter.FirstWMgrWindow(); iter.More(); aWinPtr = iter.NextWMgrWindow())
  2114.     {
  2115.         TWindow* aWindow = this->WMgrToWindow(aWinPtr);
  2116.     
  2117.         if (aWindow && TestWindow(aWindow, staticLink))
  2118.         {
  2119.             // Convert the visRgn to global coordinates 
  2120.     
  2121. //###SRF            SetPort(aWinPtr);
  2122.             aWindow->LocalToSuperRgn(aWinPtr->visRgn);
  2123.     
  2124.             // Remove the visRgn from the cursor region 
  2125.             DiffRgn(deskTopRgn, aWinPtr->visRgn, deskTopRgn);
  2126.     
  2127.             // Convert the visRgn back to local (port) coordinates 
  2128.             aWindow->SuperToLocalRgn(aWinPtr->visRgn);
  2129.         }
  2130.     }
  2131.     SetPort(savedPort);
  2132. }
  2133.  
  2134. //--------------------------------------------------------------------------------------------------
  2135. #pragma segment MAApplicationRes
  2136.  
  2137. pascal Boolean WindowHandlesCursor(TWindow* aWindow,
  2138.                                    void*)
  2139. {
  2140.     return ((aWindow->IsShown()) && (aWindow->HandlesCursor()));
  2141. }
  2142.  
  2143.  
  2144. // Make the region the desktop less the active window, and any first click windows.
  2145. // The current mouse location is added.
  2146. pascal void TApplication::GetDefaultCursorRgn(Point/* globalMouse */,
  2147.                                               RgnHandle cursorRgn)
  2148. {
  2149.     // Start off with the "desktop region" 
  2150.     GetDeskTopRegion(cursorRgn);
  2151.  
  2152.     // Remove the visRgn of all windows which claim the cursor 
  2153.     this->ExcludeWindowRegions(cursorRgn, WindowHandlesCursor, this);
  2154.  
  2155.     // make sure mouse's current location is included 
  2156.     //!!!RCR Done in TrackCursor. PtAndRgn(globalMouse, cursorRgn);
  2157. }
  2158.  
  2159. //--------------------------------------------------------------------------------------------------
  2160. #pragma segment MAApplicationRes
  2161.  
  2162. pascal Boolean WindowHandlesHelp(TWindow* aWindow,
  2163.                                  void*)
  2164. {
  2165.     return ((aWindow->IsShown()) && (aWindow->HandlesHelp()));
  2166. }
  2167.  
  2168. // Make the region the desktop less the active window, and any first click windows.
  2169. // The current mouse location is added.
  2170. pascal void TApplication::GetDefaultHelpRgn(Point /* globalMouse */,
  2171.                                             RgnHandle helpRgn)
  2172. {
  2173.     // Start off with the "desktop region" 
  2174.     GetDeskTopRegion(helpRgn);
  2175.  
  2176.     // Remove the visRgn of all windows which handle help 
  2177.     this->ExcludeWindowRegions(helpRgn, WindowHandlesHelp, this);
  2178.  
  2179.     // make sure mouse's current location is included 
  2180.     //!!!RCR Done in TrackCursor. PtAndRgn(globalMouse, helpRgn);
  2181.  
  2182. }
  2183.  
  2184. //--------------------------------------------------------------------------------------------------
  2185. #pragma segment MAApplicationRes
  2186.  
  2187. pascal RgnHandle TApplication::GetSleepRgn(void)
  2188. {
  2189.     Point globalMouse;
  2190.     Boolean isSleepInvalid;
  2191.  
  2192.     if (this->IsFrontProcess())
  2193.     {
  2194.         // Compute based on where the mouse is right NOW 
  2195.         GetMouse(globalMouse);
  2196.         LocalToGlobal(globalMouse);
  2197.  
  2198.         isSleepInvalid = FALSE;
  2199.  
  2200.         // The help region is computed before the cursor rgn so that
  2201.         // the cursor region excludes the balloon shape
  2202.         if ((this->IsHelpRgnInvalid()) && (this->IsHelpEnabled()))
  2203.         {
  2204.             this->TrackHelp(globalMouse);
  2205.             isSleepInvalid = TRUE;
  2206.         }
  2207.  
  2208.         if (this->IsCursorRgnInvalid())
  2209.         {
  2210.             this->TrackCursor(globalMouse);
  2211.             isSleepInvalid = TRUE;
  2212.         }
  2213.  
  2214.         if (isSleepInvalid)
  2215.             if (this->IsHelpEnabled())
  2216.                 SectRgn(fCursorRgn, fHelpRgn, fSleepRgn);
  2217.             else
  2218.                 CopyRgn(fCursorRgn, fSleepRgn);
  2219.  
  2220.         // Ensure that the sleep region contains the mouse. 
  2221.         PtAndRgn(globalMouse, fSleepRgn);
  2222.  
  2223.         return fSleepRgn;
  2224.     }
  2225.     else
  2226.         return NULL;
  2227. }
  2228.  
  2229. //--------------------------------------------------------------------------------------------------
  2230. #pragma segment MAInspector
  2231.  
  2232. pascal void TApplication::GetInspectorName(Str255& inspectorName)
  2233. {
  2234.     if (this == gApplication)
  2235.         inspectorName = "gApplication";
  2236. }
  2237.  
  2238. //--------------------------------------------------------------------------------------------------
  2239. #pragma segment MAApplicationRes
  2240.  
  2241. pascal TToolboxEvent* TApplication::GetEvent(short eventMask,
  2242.                                             long sleep,
  2243.                                             RgnHandle sleepRgn)
  2244. {
  2245.     const short osMask = app4Mask;                // One wonders when this will be in the interfaces
  2246.     
  2247. #if qPerform
  2248.     Boolean oldSetting;
  2249. #endif
  2250.  
  2251. #if qDebug
  2252.     CGrafPort desktopPort;                        // Used for showing cursor region 
  2253.     long ticks;                                    // Used for showing cursor region 
  2254.     GrafPtr savedPort;                            // Used for showing cursor region 
  2255. #endif
  2256.  
  2257.     EventRecord anEvent;
  2258.     TToolboxEvent * aTEvent;
  2259.     TToolboxEvent * returnValue;
  2260.  
  2261. #if qDebug
  2262.     --gRsrcCheck;
  2263.     if (gRsrcCheck <= 0)
  2264.     {
  2265.         CheckRsrcUsage();
  2266.         gRsrcCheck = kRsrcCheckInterval;
  2267.     }
  2268. #endif
  2269.  
  2270.     if (gIntenseDebugging && gReportEvt)
  2271.     {
  2272.         fprintf(stderr, "WaitNextEvent: sleep=0%d", sleep);
  2273.         // faceless driver bug fixed in MF 7.0 
  2274.         if (sleepRgn == NULL)
  2275.             fprintf(stderr, ", sleep region=NULL");
  2276.         else
  2277.             WrLblRect(", sleep region", (*sleepRgn)->rgnBBox);
  2278.         fprintf(stderr, "\n");
  2279.  
  2280.     }
  2281.  
  2282. #if qDebug
  2283.     if (gShowCursorRegion || gShowHelpRegion || gShowSleepRegion)
  2284.     {
  2285.         // Cursor region is in global coords. Need to create desktop port 
  2286.         GetPort(savedPort);
  2287.         if (qNeedsColorQD || gConfiguration.hasColorQD)
  2288.             OpenCPort(&desktopPort);
  2289.         else
  2290.             OpenPort((GrafPtr) & desktopPort);
  2291.         CopyRgn(GetGrayRgn(), desktopPort.visRgn);
  2292.         desktopPort.portRect = (*(desktopPort.visRgn))->rgnBBox;
  2293.  
  2294.         PenNormal();
  2295.         PenMode(patXor);
  2296.  
  2297.         if (gShowCursorRegion)
  2298.         {
  2299.             PaintRgn(fCursorRgn);
  2300.             Delay(30, ticks);
  2301.             PaintRgn(fCursorRgn);
  2302.         }
  2303.  
  2304.         if (gShowHelpRegion)
  2305.         {
  2306.             PaintRgn(fHelpRgn);
  2307.             Delay(30, ticks);
  2308.             PaintRgn(fHelpRgn);
  2309.         }
  2310.  
  2311.         if (gShowSleepRegion)
  2312.         {
  2313.             PaintRgn(fSleepRgn);
  2314.             Delay(30, ticks);
  2315.             PaintRgn(fSleepRgn);
  2316.         }
  2317.  
  2318.         sleep = 60;
  2319.  
  2320.         if (qNeedsColorQD || gConfiguration.hasColorQD)
  2321.             CloseCPort(&desktopPort);
  2322.         else
  2323.             ClosePort((GrafPtr) & desktopPort);
  2324.         SetPort(savedPort);
  2325.     }
  2326.  
  2327. #endif
  2328.  
  2329.     this->ActivateBusyCursor(FALSE);            // Turn off busy cursor while we're away.
  2330.  
  2331. #if qPerform
  2332.     oldSetting = DebugPerfMonitor(FALSE);
  2333. #endif
  2334.  
  2335.     // SystemEvents aren't queued and will be lost if not retrieved when available. So we
  2336.     // ensure here that they are always retrieved by adding osMask.
  2337.  
  2338.     if (WaitNextEvent(((eventMask) | osMask), anEvent, sleep, sleepRgn))
  2339.     {
  2340.         aTEvent = new TToolboxEvent;            // ###!!!SRF use a cacheing system 
  2341.         aTEvent->IToolboxEvent(this);
  2342.         aTEvent->HaveEvent(anEvent);
  2343.         returnValue = aTEvent;
  2344.     }
  2345.     else
  2346.         returnValue = NULL;
  2347.  
  2348. #if qPerform
  2349.     DebugPerfMonitor(oldSetting);
  2350. #endif
  2351.  
  2352.     if (this->IsFrontProcess())                    // If we're not in the background, then 
  2353.         this->ActivateBusyCursor(TRUE);            // â€¦enable the busy cursor mechanism. 
  2354.     return returnValue;
  2355. }
  2356.  
  2357. //--------------------------------------------------------------------------------------------------
  2358. #pragma segment MAUtilitiesRes
  2359.  
  2360. pascal void EachWMgrWindowDoTill(pascal Boolean(* DoToWMgrWindow)(WindowPtr theWMgrWindow,
  2361.                                                                   void* staticLink),
  2362.                                  void* staticLink)
  2363. {
  2364.     CWMgrIterator iter;
  2365.     
  2366.     for (WindowPtr aWindowPtr = iter.FirstWMgrWindow(); iter.More(); aWindowPtr = iter.NextWMgrWindow())
  2367.         if (!DoToWMgrWindow(aWindowPtr, staticLink))
  2368.             break;
  2369. }
  2370.  
  2371. //--------------------------------------------------------------------------------------------------
  2372. #pragma segment MAApplicationRes
  2373.  
  2374. pascal TWindow* TApplication::GetFrontWindow(void)
  2375. {
  2376.     if (qNeedsProcessMgr || gConfiguration.hasProcessMgr ||!IsDeskAccessory(FrontWindow()))
  2377.     {
  2378.         CWMgrIterator iter;
  2379.         
  2380.         for (WindowPtr aWinPtr = iter.FirstWMgrWindow(); iter.More(); aWinPtr = iter.NextWMgrWindow())
  2381.         {
  2382.             TWindow* aWindow = this->WMgrToWindow(aWinPtr);
  2383.         
  2384.             if ((aWindow) && (aWindow->IsShown()) && (!aWindow->fFloats))
  2385.                 return aWindow;
  2386.         }
  2387.     }
  2388.     return NULL;
  2389. }
  2390.  
  2391. //--------------------------------------------------------------------------------------------------
  2392. #pragma segment MAApplicationRes
  2393.  
  2394. pascal TWindow* TApplication::GetActiveWindow(void)
  2395. {
  2396.     if (qNeedsProcessMgr || gConfiguration.hasProcessMgr ||!IsDeskAccessory(FrontWindow()))
  2397.     {
  2398.         CWMgrIterator iter;
  2399.         
  2400.         for (WindowPtr aWinPtr = iter.FirstWMgrWindow(); iter.More(); aWinPtr = iter.NextWMgrWindow())
  2401.         {
  2402.             TWindow* aWindow = this->WMgrToWindow(aWinPtr);
  2403.         
  2404.             if ((aWindow) && (aWindow->IsShown()) && (aWindow->IsActive()) && (!aWindow->fFloats))
  2405.                 return aWindow;
  2406.         }
  2407.     }
  2408.     return NULL;
  2409. }
  2410.  
  2411. //--------------------------------------------------------------------------------------------------
  2412. #pragma segment MAApplicationRes
  2413.  
  2414. pascal TCommand* TApplication::GetLastCommand(void)
  2415. {
  2416.     return fLastCommand;
  2417. }
  2418.  
  2419. //--------------------------------------------------------------------------------------------------
  2420. #pragma segment MAApplicationRes
  2421.  
  2422. pascal TEvent* TApplication::RetrieveAnEvent(void)
  2423. {
  2424.     TEvent * anEvent;
  2425.  
  2426.     if (!fEventList->IsEmpty())
  2427.     {
  2428.         // Higher priority events are at the end of the list.
  2429.         CObjectIterator iter(fEventList, kIterateBackward);
  2430.         
  2431.         for (TEvent* itsEvent = (TEvent*)iter.FirstObject(); iter.More(); itsEvent = (TEvent*)iter.NextObject())
  2432.         {
  2433.             if (itsEvent->IsReadyToExecute())
  2434.             {
  2435.                 anEvent = itsEvent;
  2436.                 break;
  2437.             }
  2438.         }
  2439.  
  2440.         if ((anEvent) && !anEvent->IsRecurring())
  2441.             fEventList->Delete(anEvent);
  2442.         return anEvent;
  2443.     }
  2444.     else
  2445.         return NULL;
  2446. }
  2447.  
  2448. //--------------------------------------------------------------------------------------------------
  2449. #pragma segment MAOpen
  2450.  
  2451. // ??? We should not muck with the window template; the extra code isn't worth it since
  2452. // programmer can easily change the resource file ???
  2453. pascal WindowPtr TApplication::GetRsrcWindow(Ptr storage,
  2454.                                              short rsrcId,
  2455.                                              Boolean& isResizable,
  2456.                                              Boolean& isClosable)
  2457. // We force INVISIBLE in the WIND definition so the screen won't flash. 
  2458. {
  2459.     struct WINDTemplate
  2460.     {
  2461.         Rect bounds;
  2462.         short procID;
  2463.         Boolean visible, filler1;
  2464.         Boolean goAway, filler2;
  2465.         long refcon;
  2466.         short itemsID;                            // only for DLOG resource 
  2467.     };
  2468.  
  2469.  
  2470.     typedef WINDTemplate* WINDTemplatePtr, ** WINDTemplateHandle;
  2471.  
  2472.     WindowPtr aWMgrWindow;
  2473.     WINDTemplateHandle templateHandle;
  2474.     Boolean oldPerm;
  2475.     FailInfo fi;
  2476.  
  2477.     VOLATILE(oldPerm);
  2478.     
  2479.     // Even though the window is permanent, we allocate it under a temporary flag so that the
  2480.     // maximum memory is available. Quickdraw can blow up if it can't allocate a grafPort.
  2481.     oldPerm = PermAllocation(FALSE);
  2482.  
  2483.     if (fi.Try())
  2484.     {
  2485.         templateHandle = (WINDTemplateHandle) GetResource('WIND', rsrcId);
  2486.         FailNILResource((Handle)templateHandle);
  2487.         MoveHHi((Handle)templateHandle);        // in case it is locked by the ROM 
  2488.  
  2489.         WINDTemplate& templateData = **templateHandle;
  2490.         templateData.visible = FALSE;
  2491.         isClosable = templateData.goAway;
  2492.         isResizable = ((templateData.procID == documentProc) || (templateData.procID == zoomDocProc));
  2493.         // If your own defProc is resizable, too, then after the call on GetRsrcWindow, set
  2494.         // isResizable TRUE 
  2495.  
  2496.         if (qNeedsColorQD || gConfiguration.hasColorQD)
  2497.             aWMgrWindow = (WindowPtr)(GetNewCWindow(rsrcId, (Ptr)(storage), (WindowPtr)(-1)));
  2498.         else
  2499.             aWMgrWindow = GetNewWindow(rsrcId, (Ptr)(storage), (WindowPtr)(-1));
  2500.  
  2501.         FailNIL(aWMgrWindow);
  2502.         oldPerm = PermAllocation(oldPerm);
  2503.         fi.Success();
  2504.     }
  2505.     else    // Recover. Don't need the failure handler since we've set the perm allocation flag back.
  2506.     {
  2507.         // Make sure the perm allocation flag is set back to what it was
  2508.         // when we entered GetRsrcWindow.
  2509.         oldPerm = PermAllocation(oldPerm);
  2510.         fi.ReSignal();
  2511.     }
  2512.  
  2513.     // Now we must make sure that the code reserve is still intact.
  2514.     if (!CheckReserve())
  2515.     {
  2516.         aWMgrWindow = FreeIfWMgrWindow(aWMgrWindow, storage == NULL);
  2517.  
  2518.         Failure(memFullErr, 0);
  2519.     }
  2520.  
  2521.     return aWMgrWindow;
  2522. }
  2523.  
  2524. //--------------------------------------------------------------------------------------------------
  2525. #pragma segment MAApplicationRes
  2526.  
  2527. pascal TEvtHandler* TApplication::GetTarget(void)
  2528. {
  2529.     return fTarget;
  2530. }
  2531.  
  2532. //--------------------------------------------------------------------------------------------------
  2533. #pragma segment MAApplicationRes
  2534.  
  2535. pascal void TApplication::HandleActivateEvent(TToolboxEvent* event)
  2536. {
  2537.     TWindow * aWindow;
  2538.  
  2539.     aWindow = this->WMgrToWindow((WindowPtr)(event->fEventRecord.message));
  2540.     if (aWindow)
  2541.         aWindow->Activate(((event->fEventRecord.modifiers) & activeFlag) != 0);
  2542.     else
  2543.         this->HandleAlienEvent(event);
  2544. }
  2545.  
  2546. //--------------------------------------------------------------------------------------------------
  2547. #pragma segment MAApplicationRes
  2548.  
  2549. pascal void TApplication::HandleAlienEvent(TEvent* event)
  2550. {
  2551.     CHandlerIterator iter(fHeadCohandler);
  2552.     
  2553.     for (TEvtHandler* aHandler = iter.FirstHandler(); iter.More(); aHandler = iter.NextHandler())
  2554.         if (aHandler->DoCoHandlerEvent(event))
  2555.             break;
  2556. }
  2557.  
  2558. //--------------------------------------------------------------------------------------------------
  2559. #pragma segment MADoCommand
  2560.  
  2561. pascal void TApplication::HandleDiskEvent(TToolboxEvent* event)
  2562. {
  2563.     const Point topLeft(0x50, 0x70);
  2564.  
  2565.     short err;
  2566.  
  2567.     if (HiWord(event->fEventRecord.message) != noErr)
  2568.     {
  2569.         err = DIBadMount(topLeft, event->fEventRecord.message);// ??? do something with the error
  2570. #if qDebugMsg
  2571.         if (err != noErr)
  2572.             fprintf(stderr, "error from DIBadMount is %d\n", err);
  2573. #endif
  2574.  
  2575.     }
  2576. }
  2577.  
  2578. //--------------------------------------------------------------------------------------------------
  2579. #pragma segment MAApplicationRes
  2580.  
  2581. pascal void TApplication::DoEvent(EvtNumber,
  2582.                                       TEvtHandler* ,
  2583.                                       TEvent* event)// override 
  2584. {
  2585.     FailInfo fi;
  2586.     VOLATILE(event);
  2587.  
  2588. #if qDebug
  2589.     if (gReportEvt && event)
  2590.         event->ReportEvent();
  2591. #endif
  2592.  
  2593.     if (fi.Try())
  2594.     {
  2595.         this->DispatchEvent(event);
  2596.         fi.Success();
  2597.     }
  2598.     else    // Recover
  2599.     {
  2600.         this->PostDoEvent(event);
  2601.         fi.ReSignal();
  2602.     }
  2603.  
  2604.     this->PostDoEvent(event);
  2605. }
  2606.  
  2607. //--------------------------------------------------------------------------------------------------
  2608. #pragma segment MAFinder
  2609.  
  2610. pascal void TApplication::HandleFinderRequest(void)
  2611. {
  2612. #if !qNeedsAppleEventMgr
  2613.  
  2614.     AppFile anAppFile;
  2615.     TFile * aFile;
  2616.     TList * aFileList;
  2617.     CmdNumber cmd;
  2618.     FailInfo outerFi,  fi;
  2619.     long message;
  2620.     short theFileCount;
  2621.     Boolean finderPrinting;
  2622.  
  2623.     VOLATILE(aFile);
  2624.     VOLATILE(message);
  2625.     VOLATILE(anAppFile);
  2626.     VOLATILE(cmd);
  2627.  
  2628.     if (outerFi.Try())
  2629.     {
  2630. #if qDebugMsg
  2631.         if (gExperimenting)
  2632.             fprintf(stderr, "File count: %d\n", theFileCount);
  2633. #endif
  2634.  
  2635.         // determine number of files and whether it's a print from finder request 
  2636.         CountAppFiles((short)message, theFileCount);
  2637.         finderPrinting = (message == appPrint);
  2638.  
  2639.         if (theFileCount == 0)
  2640.         {
  2641.             if (IsOptionKeyDown())
  2642.                 this->HandleMenuCommand(cOpen);
  2643.             else if (fLaunchWithNewDocument)
  2644.                 this->HandleMenuCommand(cFinderNew);
  2645.         }
  2646.         else                                    /* it's an OPEN or PRINT of 1 or more existing files */
  2647.             {
  2648.             if (finderPrinting)
  2649.                 cmd = cFinderPrint;
  2650.             else
  2651.                 cmd = cFinderOpen;
  2652.  
  2653.             aFileList = NewList();
  2654.  
  2655.             for (short i = 1; i <= theFileCount; ++i)
  2656.             {
  2657.                 if (fi.Try())
  2658.                 {
  2659.                     aFile = this->DoMakeFile(cmd);
  2660.  
  2661.                     GetAppFiles(i, anAppFile);
  2662.  
  2663.                     FailOSErr(aFile->IdentifyByTrio(anAppFile.vRefNum, 0, (Str63)anAppFile.fName));
  2664.                     aFile->fFileType = anAppFile.fType;
  2665.  
  2666.                     if (this->CanOpenDocument(cmd, aFile))
  2667.                     {
  2668.                         ClrAppFiles(i);
  2669.                         aFileList->InsertLast(aFile);
  2670.                     }
  2671.                     else
  2672.                         Failure(errNotMyType, 0);
  2673.                     fi.Success();
  2674.                 }
  2675.                 else    // Recover
  2676.                 {
  2677.                     if (fi.error != noErr)
  2678.                     {
  2679.                         aFile = (TFile *)(FreeIfObject(aFile));
  2680.                         if (message == 0)
  2681.                         {
  2682.                             gErrorParm3 = (Str255)anAppFile.fName;
  2683.                             if (cmd == cFinderPrint)
  2684.                                 message = msgPrintFailed;
  2685.                             else
  2686.                                 message = msgOpenFailed;
  2687.                         }
  2688.                         this->ShowError(fi.error, message);
  2689.                     }
  2690.                 }
  2691.             }
  2692.  
  2693.             if (finderPrinting)
  2694.             {
  2695.                 TPDocCommand* aPDocCommand;
  2696.                 
  2697.                 aPDocCommand = new TPDocCommand;
  2698.                 aPDocCommand->IPDocCommand(cFinderPrint, aFileList);
  2699.                 this->PostCommand(aPDocCommand);
  2700.             }
  2701.             else
  2702.             {
  2703.                 TODocCommand * anODocCommand;
  2704.                 
  2705.                 anODocCommand = new TODocCommand;
  2706.                 anODocCommand->IODocCommand(cFinderOpen, aFileList);
  2707.                 this->PostCommand(anODocCommand);
  2708.             }
  2709.         }
  2710.         outerFi.Success();
  2711.     }
  2712.     else    // Recover
  2713.     {
  2714.         if (outerFi.error != noErr)
  2715.             this->ShowError(outerFi.error, message);    // PollEvents' error handler not in place yet
  2716.     }
  2717. #endif
  2718. }
  2719.  
  2720. //--------------------------------------------------------------------------------------------------
  2721. #pragma segment MAApplicationRes
  2722.  
  2723. // Assume that the high level event received was an Apple Event and process it.    This will 
  2724. // dispatch to us via MAGeneralDispatch.
  2725.  
  2726. pascal void TApplication::HandleHighLevelEvent(TToolboxEvent* event)
  2727. {
  2728.     EventRecord anEventRecord;
  2729.     OSErr theErr;
  2730.  
  2731.     this->SetupTheMenus();                        // Make sure that the menus are setup
  2732.                                                 // correctly before we handle the event
  2733.     anEventRecord = event->fEventRecord;
  2734.     
  2735.     theErr = AEProcessAppleEvent(anEventRecord);
  2736.     if (theErr != errAEEventNotHandled)            // If the event is one we don't handle, do nothing
  2737.         FailOSErr(theErr);
  2738. }
  2739.  
  2740. //--------------------------------------------------------------------------------------------------
  2741. #pragma segment MAApplicationRes
  2742.  
  2743. pascal void TApplication::HandleKeyDownEvent(TToolboxEvent* event)
  2744. {
  2745.     this->GetTarget()->KeyEventToComponents(event);// Find out what keys were _REALLY_ pressed 
  2746.  
  2747.     if (event->fCmdKey)
  2748.         this->GetTarget()->HandleCommandKey(event);
  2749.     else
  2750.         this->GetTarget()->HandleKeyCommand(event);
  2751. }
  2752.  
  2753. //--------------------------------------------------------------------------------------------------
  2754. #pragma segment MAApplicationRes
  2755.  
  2756. pascal void TApplication::HandleMouseDown(TToolboxEvent* event)
  2757. {
  2758.     TWindow * aWindow;
  2759.     WindowPtr aWMgrWindow;
  2760.     short whereMouseDown;
  2761.     EventRecord anEventRecord;
  2762.  
  2763.     whereMouseDown = FindWindow(event->fEventRecord.where, aWMgrWindow);
  2764.     event->fClickCount = this->CountClicks(event, whereMouseDown);
  2765.  
  2766.     aWindow = this->WMgrToWindow(aWMgrWindow);
  2767.  
  2768.     if (((whereMouseDown == inMenuBar) && (this->InModalMenuState())) || ((whereMouseDown != inMenuBar) && this->InModalState() && (aWindow != (this->GetActiveWindow()))))
  2769.     {
  2770.         this->Beep(2);
  2771.         return ();                                // exit(HandleMouseDown);
  2772.     }
  2773.  
  2774.     switch (whereMouseDown)
  2775.     {
  2776.         case inMenuBar:
  2777.             this->SetupTheMenus();                // gives application a chance to setup individual menu items
  2778.             this->MenuEvent(MenuSelect(event->fEventRecord.where));
  2779.             break;
  2780.  
  2781.         case inSysWindow:
  2782.             anEventRecord = event->fEventRecord;
  2783.             SystemClick(anEventRecord, aWMgrWindow);
  2784.             break;
  2785.  
  2786.         default:                                // if a MacApp window was associated with the WindowPtr then let the window object decide
  2787.                                                 // what to do with the mouse click
  2788.             if (aWindow)
  2789.             {
  2790.                 if (aWindow->Focus())            // if we can't focus, we're in trouble 
  2791.                 {
  2792.                     VPoint theMouse(event->fEventRecord.where);
  2793.                     aWindow->SuperToLocal(theMouse);
  2794.                     aWindow->HandleMouseDown(theMouse, event, gStdHysteresis);
  2795.                 }
  2796.                 else if (qDebug)
  2797.                     ProgramBreak("In TApplication.HandleMouseDown: couldn''t focus on a window object!");
  2798.             }
  2799.             else
  2800.                 this->HandleAlienEvent(event);
  2801.             break;
  2802.  
  2803.     }
  2804.     fLastUpTime = TickCount();                    // Because the toolbox often eats mouseUpEvents remember the time on the way out for
  2805.                                                 // double/ triple detection.
  2806. }
  2807.  
  2808. //--------------------------------------------------------------------------------------------------
  2809. #pragma segment MAApplicationRes
  2810.  
  2811. pascal void TApplication::HandleMouseUp(TToolboxEvent* event)
  2812. {
  2813.     TWindow * aWindow;
  2814.     WindowPtr aWMgrWindow;
  2815.     short whereMouseDown;
  2816.  
  2817.     // Remember time of last mouse up, in order to detect double/triple (multiple) clicks 
  2818.     fLastUpTime = event->fEventRecord.when;
  2819.  
  2820.     whereMouseDown = FindWindow(event->fEventRecord.where, aWMgrWindow);
  2821.     aWindow = this->WMgrToWindow(aWMgrWindow);
  2822.  
  2823.     switch (whereMouseDown)
  2824.     {
  2825.         case inMenuBar:
  2826.             break;
  2827.             
  2828.         case inSysWindow:
  2829.             break;
  2830.             
  2831.         default:
  2832.             if (aWindow == NULL)
  2833.                 this->HandleAlienEvent(event);    // handle non-MacApp windows 
  2834.             break;
  2835.     }
  2836. }
  2837.  
  2838. //--------------------------------------------------------------------------------------------------
  2839. #pragma segment MAApplicationRes
  2840.  
  2841. pascal void TApplication::HandleSystemEvent(TToolboxEvent* event)
  2842. {
  2843.     WindowPtr aWindowPtr;
  2844.     TWindow * aWindow;
  2845.     Boolean switchingIn;
  2846.     Boolean convertClipboard;
  2847.  
  2848.  
  2849.     switch (((unsigned long)(event->fEventRecord.message & osEvtMessageMask)) >> 24)
  2850.     {
  2851.         case suspendResumeMessage:
  2852.             switchingIn = ((event->fEventRecord.message) & resumeFlag) != 0;
  2853.             convertClipboard = ((event->fEventRecord.message) & convertClipboardFlag) != 0;
  2854.  
  2855.             if (switchingIn)
  2856.                 this->RegainControl(convertClipboard);
  2857.             else
  2858.                 this->AboutToLoseControl(convertClipboard);
  2859.  
  2860.             if (switchingIn)
  2861.                 aWindow = this->GetFrontWindow();
  2862.             else
  2863.                 aWindow = this->GetActiveWindow();
  2864.  
  2865.             if (aWindow)
  2866.                 aWindow->Activate(switchingIn);
  2867.  
  2868.             // when switching out, after having hid windows that get hid on suspend in
  2869.             // AboutToLoseControl, we need to ensure that our idea about the front window
  2870.             // and the Process Manager's idea about the front window are the same
  2871.             if (!switchingIn)
  2872.             {
  2873.                 aWindowPtr = MAFrontWindow();
  2874.                 if (aWindowPtr)
  2875.                     BringToFront(aWindowPtr);
  2876.             }
  2877.  
  2878.             if (!(qNeedsProcessMgr || gConfiguration.hasProcessMgr))
  2879.                 fInBackground =!switchingIn;
  2880.  
  2881.             this->InvalidateMouseRegions();
  2882.             break;
  2883.             
  2884.         case mouseMovedMessage:
  2885.             event->fAffectsMenus = FALSE;        // We don't think mouse tracking usually bothers the menus.
  2886.             // We got the mouse moved event because the mouse strayed outside of fSleepRgn. It may or
  2887.             // may not have strayed outside of the other mouse regions. We'll only
  2888.             // invalidate them here (if necessary) because that way we can defer computing
  2889.             // them for as long as possible.
  2890.             if (!PtInRgn(event->fEventRecord.where, fCursorRgn))
  2891.                 this->InvalidateCursorRgn();
  2892.             if (!PtInRgn(event->fEventRecord.where, fHelpRgn))
  2893.                 this->InvalidateHelpRgn();
  2894.             break;
  2895.             
  2896.         default:
  2897.             if (gIntenseDebugging)
  2898.                 fprintf(stderr, "in TApplication.HandleSystemEvent: got unrecognized event\n");
  2899.             break;
  2900.     }
  2901. }
  2902.  
  2903. //--------------------------------------------------------------------------------------------------
  2904. #pragma segment MAApplicationRes
  2905.  
  2906. pascal void TApplication::HandleUpdateEvent(TToolboxEvent* event)
  2907. {
  2908.     TWindow * aWindow;
  2909.  
  2910.     aWindow = this->WMgrToWindow((WindowPtr) event->fEventRecord.message);
  2911.     if (aWindow)
  2912.         aWindow->Update();
  2913.     else
  2914.         this->HandleAlienEvent(event);
  2915. }
  2916.  
  2917. //--------------------------------------------------------------------------------------------------
  2918. #pragma segment MAApplicationRes
  2919.  
  2920. pascal void TApplication::Idle(IdlePhase phase)
  2921. {
  2922.     FailInfo fi;
  2923. #if qDebug
  2924.     Boolean wasTrcEnable;
  2925. #endif
  2926.  
  2927.     if (fi.Try())
  2928.     {
  2929. #if qDebug
  2930.         wasTrcEnable = TrcEnable(gTraceIdle);    // Trace during idle only if user wants to. 
  2931. #endif
  2932.         if (phase == idleBegin)
  2933.         {
  2934.             if (!gInFilter && MemSpaceIsLow())
  2935.                 this->SpaceIsLow();
  2936.             else
  2937.                 fNextSpaceMsg = TickCount();
  2938.         }
  2939.  
  2940.         // Create a new block for failure handling
  2941.         {
  2942.             CHandlerIterator iter(fHeadCohandler);
  2943.             
  2944.             for (TEvtHandler* aHandler = iter.FirstHandler(); iter.More(); aHandler = iter.NextHandler())
  2945.                 aHandler->HandleIdle(phase);
  2946.         }
  2947.  
  2948.         if (qDebug)
  2949.             Assertion(this->GetTarget() != NULL, "GetTarget != nil");
  2950.             
  2951.         // Create a new block for failure handling
  2952.         {
  2953.             CHandlerIterator iter(this->GetTarget());
  2954.             
  2955.             for (TEvtHandler* aHandler = iter.FirstHandler(); iter.More(); aHandler = iter.NextHandler())
  2956.                 aHandler->HandleIdle(phase);
  2957.         }
  2958.  
  2959. #if qDebug
  2960.         TrcEnable(wasTrcEnable);                // restore tracing state at end of idle.
  2961. #endif
  2962.         fi.Success();
  2963.     }
  2964.     else    // Recover
  2965.     {
  2966.         gInhibitNestedHandling = TRUE;            // Don't want to come back into Idle From
  2967.                                                 // alert filters or other strange places
  2968.         fi.ReSignal();
  2969.     }
  2970. }
  2971.  
  2972. //--------------------------------------------------------------------------------------------------
  2973. #pragma segment MAApplicationRes
  2974.  
  2975. pascal long TApplication::GetWaitTicks(Boolean allowApplicationToSleep)
  2976. {
  2977.     const short kMaxSleep = 60;                    // max sleep in foreground so MultiFinder
  2978.                                                 // gives time to non-desk accessory drivers
  2979.  
  2980. #if qDebug
  2981.     Boolean wasTrcEnable;
  2982. #endif
  2983.     long returnValue = 0;
  2984.  
  2985. #if qDebug
  2986.     wasTrcEnable = TrcEnable(gTraceIdle);        // Trace during idle only if user wants to. 
  2987. #endif
  2988.  
  2989.     if (allowApplicationToSleep)
  2990.     {
  2991.         long compositeTicks = kMaxIdleTime;
  2992.  
  2993.         // Check the cohandler chain first.  Add new block for failure handling
  2994.         {
  2995.             CHandlerIterator iter(fHeadCohandler);
  2996.             
  2997.             for (TEvtHandler* aHandler = iter.FirstHandler(); iter.More(); aHandler = iter.NextHandler())
  2998.                 compositeTicks = Min(compositeTicks, Max(aHandler->NextIdle() - TickCount(), 0));
  2999.         }
  3000.  
  3001.         if (qDebug)
  3002.             Assertion(this->GetTarget() != NULL, "GetTarget != nil");
  3003.             
  3004.         // now run through the target chain.  Add new block for failure handling
  3005.         {
  3006.             CHandlerIterator iter(this->GetTarget());
  3007.             
  3008.             for (TEvtHandler* aHandler = iter.FirstHandler(); iter.More(); aHandler = iter.NextHandler())
  3009.                 compositeTicks = Min(compositeTicks, Max(aHandler->NextIdle() - TickCount(), 0));
  3010.         }
  3011.  
  3012.         // faceless driver bug in M.F fixed in process manager 
  3013.         if (qNeedsProcessMgr || gConfiguration.hasProcessMgr)
  3014.             returnValue = compositeTicks;
  3015.         else if ((compositeTicks > kMaxSleep) && this->IsFrontProcess())
  3016.         {
  3017.             if (gIntenseDebugging && gReportEvt)
  3018.                 fprintf(stderr, "IN TApplication.GetWaitTicks: clipped to MaxSleep=%d\n", kMaxSleep);
  3019.             returnValue = Min(compositeTicks, kMaxSleep);
  3020.         }
  3021.     }
  3022.  
  3023. #if qDebug
  3024.     TrcEnable(wasTrcEnable);                // restore tracing state at end of idle.
  3025. #endif
  3026.  
  3027.     return returnValue;
  3028. }
  3029.  
  3030. //--------------------------------------------------------------------------------------------------
  3031. #pragma segment MAApplicationRes
  3032.  
  3033. pascal Boolean TApplication::InModalState(void)
  3034. {
  3035.     TWindow * aWindow;
  3036.     WindowPtr aWindowPtr;
  3037.  
  3038.     aWindowPtr = FrontWindow();
  3039.  
  3040.     // in case the front window is an alert or something 
  3041.     if ((this->WMgrToWindow(aWindowPtr) == NULL) && (aWindowPtr))
  3042.         switch (GetWindowVariant(aWindowPtr))
  3043.         {
  3044.             case dBoxProc:
  3045.             case plainDBox:
  3046.             case altDBoxProc:
  3047.                 return TRUE;
  3048.             default:
  3049.                 return FALSE;
  3050.         }
  3051.     else
  3052.     {
  3053.         aWindow = this->GetActiveWindow();
  3054.         return ((aWindow) && (aWindow->fIsModal));
  3055.     }
  3056. }
  3057.  
  3058. //--------------------------------------------------------------------------------------------------
  3059. #pragma segment MAApplicationRes
  3060.  
  3061. pascal Boolean TApplication::InModalMenuState(void)
  3062. {
  3063.     TWindow * aWindow;
  3064.     WindowPtr aWindowPtr;
  3065.  
  3066.     aWindowPtr = FrontWindow();
  3067.  
  3068.     // in case the front window is an alert or something 
  3069.  
  3070.     if ((this->WMgrToWindow(aWindowPtr) == NULL) && (aWindowPtr))
  3071.         switch (GetWindowVariant(aWindowPtr))
  3072.         {
  3073.             case dBoxProc:
  3074.             case plainDBox:
  3075.             case altDBoxProc:
  3076.                 return TRUE;
  3077.             default:
  3078.                 return FALSE;
  3079.         }
  3080.     else
  3081.     {
  3082.         aWindow = this->GetActiveWindow();
  3083.         return ((aWindow) && !aWindow->AllowsMenuAccess());
  3084.     }
  3085. }
  3086.  
  3087. //--------------------------------------------------------------------------------------------------
  3088. #pragma segment MANonRes
  3089.  
  3090. pascal void TApplication::InstallCohandler(TEvtHandler* aCohandler,
  3091.                                            Boolean addIt)
  3092. {
  3093.     if (addIt)
  3094.         fHeadCohandler = aCohandler->AddHandler(fHeadCohandler);
  3095.     else
  3096.         fHeadCohandler = aCohandler->RemoveHandler(fHeadCohandler);
  3097. }
  3098.  
  3099. //--------------------------------------------------------------------------------------------------
  3100. #pragma segment MAApplicationRes
  3101.  
  3102. pascal Boolean TApplication::IsDeskAccessory(WindowPtr aWMgrWindow)
  3103. {
  3104.     return (!(qNeedsProcessMgr || gConfiguration.hasProcessMgr) && ((aWMgrWindow) && (WindowPeek(aWMgrWindow)->windowKind < 0)));
  3105. }
  3106.  
  3107. //--------------------------------------------------------------------------------------------------
  3108. #pragma segment MAApplicationRes
  3109.  
  3110. pascal Boolean TApplication::IsFrontProcess(void)
  3111. {
  3112.     ProcessSerialNumber aPSN;
  3113.     ProcessSerialNumber applicationPSN;
  3114.     Boolean result;
  3115.  
  3116.     if (qNeedsProcessMgr || gConfiguration.hasProcessMgr)
  3117.     {
  3118.         FailOSErr(GetFrontProcess(aPSN));
  3119.         applicationPSN = fApplicationPSN;
  3120.         FailOSErr(SameProcess(aPSN, applicationPSN, result));
  3121.         return result;
  3122.     }
  3123.     else
  3124.         return !fInBackground;
  3125. }
  3126.  
  3127. //--------------------------------------------------------------------------------------------------
  3128. #pragma segment MAApplicationRes
  3129.  
  3130. pascal void TApplication::MakeFrontProcess(void)
  3131. {
  3132.     if (!this->IsFrontProcess())
  3133.     {
  3134.         ProcessSerialNumber aPSN = fApplicationPSN;
  3135.         FailOSErr(SetFrontProcess(aPSN));
  3136.     }
  3137. }
  3138.  
  3139. //--------------------------------------------------------------------------------------------------
  3140. #pragma segment MAApplicationRes
  3141.  
  3142. pascal Boolean TApplication::IsHelpEnabled(void)
  3143. {
  3144.     if (qNeedsHelpMgr || gConfiguration.hasHelpMgr)
  3145.         return HMGetBalloons();
  3146.     else
  3147.         return FALSE;
  3148. }
  3149.  
  3150. //--------------------------------------------------------------------------------------------------
  3151. #pragma segment MAApplicationRes
  3152.  
  3153. pascal void TApplication::InvalidateMouseRegions(void)
  3154. {
  3155.     this->InvalidateCursorRgn();
  3156.     this->InvalidateHelpRgn();
  3157. }
  3158.  
  3159. //--------------------------------------------------------------------------------------------------
  3160. #pragma segment MAApplicationRes
  3161.  
  3162. pascal void TApplication::InvalidateCursorRgn(void)
  3163. {
  3164.     if (fCursorRgn)
  3165.         SetEmptyRgn(fCursorRgn);                // Make sure it gets changed back 
  3166.  
  3167.     // ###!!! most callers of invalidatecursorrgn really would want the help rgn invalidated
  3168.     // for the same reasons that the cursor rgn is invalid. Until we get them all switched
  3169.     // over to a new call like "InvalidateMouseRgns" we should just inval the help rgn too
  3170. }
  3171.  
  3172. //--------------------------------------------------------------------------------------------------
  3173. #pragma segment MAApplicationRes
  3174.  
  3175. pascal void TApplication::InvalidateHelpRgn(void)
  3176. {
  3177.     if (fHelpRgn)
  3178.         SetEmptyRgn(fHelpRgn);                    // Make sure it gets changed back 
  3179.     if (qNeedsHelpMgr || gConfiguration.hasHelpMgr)
  3180.         if (HMIsBalloon())
  3181.         {
  3182.             OSErr err = HMRemoveBalloon();
  3183.             if (err != hmNoBalloonUp)
  3184.                 FailOSErr(err);
  3185.         }
  3186. }
  3187.  
  3188. //--------------------------------------------------------------------------------------------------
  3189. #pragma segment MAApplicationRes
  3190.  
  3191. pascal void TApplication::InvalidateFocus(void)
  3192. {
  3193.     if (gFocusedView)
  3194.         gFocusedView->InvalidateFocus();
  3195. }
  3196.  
  3197. //--------------------------------------------------------------------------------------------------
  3198. #pragma segment MAApplicationRes
  3199.  
  3200. pascal Boolean TApplication::IsCursorRgnInvalid(void)
  3201. {
  3202.     // The cursor is normally tracked via MouseMoved events. But for those with special needs
  3203.     // fAlwaysTrackCursor can come to the rescue.
  3204.  
  3205.     return (EmptyRgn(fCursorRgn) || fAlwaysTrackCursor);
  3206. }
  3207.  
  3208. //--------------------------------------------------------------------------------------------------
  3209. #pragma segment MAApplicationRes
  3210.  
  3211. pascal Boolean TApplication::IsHelpRgnInvalid(void)
  3212. {
  3213.     return EmptyRgn(fHelpRgn);
  3214. }
  3215.  
  3216. //--------------------------------------------------------------------------------------------------
  3217. #pragma segment MAApplicationRes
  3218.  
  3219. pascal void TApplication::KeyEventToComponents(TToolboxEvent* event)
  3220. // See Tech Note #263 for the reason for this abomination 
  3221. {
  3222.     const short kMaskModifier = 0xFE00;            // need to strip command key from Modifiers 
  3223.     const long kMaskASCII1 = 0x000000FF;        // get key from KeyTrans return 
  3224.     const long kMaskASCII2 = 0x00FF0000;        // get key from KeyTrans return 
  3225.     const short kPeriod = '.';
  3226.     const short kUpKeyMask = 0x0080;
  3227.     const short kMAsmKeyCache = 38;                /*!!! Replace with system supplied constant
  3228.                                                   when sys 7.0 headers ship */
  3229.     // !!! Delete this record for 7.0 only operation. This is really a private record so
  3230.     // _DON'T_ use any other fields!
  3231.  
  3232.     struct MAExpandMemRec
  3233.     {
  3234.         short emVersion;                        // version of expanded memory 
  3235.         long emSize;                            // length of em 
  3236.         long emIntlGlobals;                        // international globals pointer 
  3237.         long emKeyDeadState;                    // Key1Trans, Key2Trans dead state 
  3238.         Ptr emKeyCache;                            // KCHR keyboard cache 
  3239.         long emIntlDef;                            // Reserved for Intl 
  3240.         Boolean emFirstKeyboard;                // flag byte 
  3241.         Boolean emAlign;                        // long-align until we need this storage 
  3242.         long emItlCache[4];                        // bytes in cache 
  3243.         Boolean emItlNeedUnlock;                // for pack6 
  3244.         Boolean emItlDirectGetIntl;                // for pack6 
  3245.         unsigned char emFiller[22];                // Reserved room 
  3246.     };
  3247.  
  3248.  
  3249.     typedef struct MAExpandMemRec MAExpandMemRec;
  3250.     typedef MAExpandMemRec* MAExpandMemRecPtr,
  3251.     ** MAExpandMemRecHandle;
  3252.  
  3253.     short keyCodeParameter;                        // See IM-V pp. 195 
  3254.     long keyInfo;
  3255.     long state;
  3256.     Ptr keyTransTable;
  3257.  
  3258.     inherited::KeyEventToComponents(event);        // Get default translation, if any 
  3259.  
  3260.     EventRecord& recordData = event->fEventRecord;
  3261.  
  3262.     if ((recordData.what == keyDown) || (recordData.what == autoKey))
  3263.     {
  3264.         // Now see if the command key is down. If it is, get the correct ASCII translation by
  3265.         // masking the command key out and re-translating because the command key will
  3266.         // mask the shift modifier.
  3267.  
  3268.         if (event->fCmdKey)
  3269.         {
  3270.             // set the upkey bit so KeyTrans doesn't do special deadkey processing 
  3271.             keyCodeParameter = ((((recordData.modifiers) & kMaskModifier) | event->fKeyCode) | kUpKeyMask);
  3272.  
  3273.             state = 0;
  3274.  
  3275.             // Get the correct keytable pointer. We don't want to grope the system unnecessarily so
  3276.             // use the script managers improvements if they're there.
  3277.             if (gConfiguration.systemVersion >= 0x700)
  3278.                 keyTransTable = (Ptr)(GetEnvirons(kMAsmKeyCache));
  3279.             else
  3280.                 // Fake handle.    the lomem address is a pointer to the table 
  3281.                 keyTransTable = (Ptr)((*(MAExpandMemRecHandle)(ExpandMem))->emKeyCache);
  3282.  
  3283.             keyInfo = KeyTrans(keyTransTable, keyCodeParameter, state);
  3284.  
  3285.             event->fCharacter = (unsigned char)(((keyInfo) & kMaskASCII1));
  3286.             if (event->fCharacter == (unsigned char)(0))
  3287.                 event->fCharacter = (unsigned char)((keyInfo >> kMaskASCII2) & 16);
  3288.         }
  3289.     }
  3290. }
  3291.  
  3292. //--------------------------------------------------------------------------------------------------
  3293. #pragma segment MAOpen
  3294.  
  3295. pascal CmdNumber TApplication::KindOfDocument(CmdNumber itsCmdNumber,
  3296.                                               TFile*)
  3297. {
  3298.     return itsCmdNumber;
  3299. }
  3300.  
  3301. //--------------------------------------------------------------------------------------------------
  3302. #pragma segment MAApplicationRes
  3303. // must be in the main segment 
  3304.  
  3305. pascal void TApplication::MainEventLoop(void)
  3306. {
  3307.     fIdlePhase = idleBegin;
  3308.     while (!fAppDone)
  3309.     {
  3310.         if (fIdlePhase == idleBegin)
  3311.             UnloadAllSegments();                // don't unload segs after idle has begun 
  3312.  
  3313.         // ??? should we (1) unload segs after completing idle but before doing the event? (2)
  3314.         // unload segs while processing event during background printing?
  3315.  
  3316.         this->PollEvent(kAllowApplicationToSleep);
  3317.     }                                            // fAppDone is a Boolean; that we set TRUE when the user chooses 'Quit'
  3318. }
  3319.  
  3320. //--------------------------------------------------------------------------------------------------
  3321. #pragma segment MAClipboard
  3322.  
  3323. pascal TView* TApplication::MakeViewForAlienClipboard(void)
  3324. {
  3325.     return NULL;                                // use defaults 
  3326. }
  3327.  
  3328. //--------------------------------------------------------------------------------------------------
  3329. #pragma segment MASelCommand
  3330.  
  3331. pascal void TApplication::MenuEvent(long menuItem)
  3332. {
  3333.     FailInfo fi;
  3334.     CmdNumber cmd;
  3335.     Str255 deskAccName;
  3336.     short theMenuNumber;
  3337.     short theItemNumber;
  3338.  
  3339.     theMenuNumber = HiWord(menuItem);
  3340.     theItemNumber = LoWord(menuItem);
  3341.  
  3342.     VOLATILE(cmd);
  3343.     
  3344.     if (theMenuNumber != 0)
  3345.     {
  3346.         cmd = CmdFromMenuItem(theMenuNumber, theItemNumber);
  3347.  
  3348. #if qDebugMsg
  3349.         if (cmd == cCantUndo)
  3350.         {
  3351.             fprintf(stderr, "Command number %d is reserved for MacApp.\n", cCantUndo);
  3352.             ProgramBreak("Use of reserved command number.");
  3353.         }
  3354.  
  3355.         if (gReportMenuChoices && (cmd > 0))
  3356.             fprintf(stderr, "Menu Choice Command Number == %d\n", cmd);
  3357. #endif
  3358.  
  3359.         if ((cmd < 0) && (theMenuNumber == mApple))
  3360.         {
  3361.             GetItem(MAGetMenu(mApple), theItemNumber, deskAccName);
  3362.             this->OpenDeskAccessory(deskAccName);
  3363.         }
  3364.         else if ((cmd < cEditBase) || (cmd > cEditLast) || (!SystemEdit((short)(cmd - cEditBase))))
  3365.         {
  3366.             if (fi.Try())
  3367.             {
  3368.                 if (fSysWindowActive)
  3369.                     this->ActivateBusyCursor(TRUE);
  3370.  
  3371.                 this->GetTarget()->HandleMenuCommand(cmd);
  3372.  
  3373.                 if (fSysWindowActive)
  3374.                     this->ActivateBusyCursor(FALSE);
  3375.                 fi.Success();
  3376.             }
  3377.             else    // Recover
  3378.             {
  3379.                 if (fSysWindowActive)
  3380.                     this->ActivateBusyCursor(FALSE);
  3381.  
  3382.                 FailNewMessage(fi.error, fi.message, BuildMessage((short)cmd, msgCmdErr));
  3383.                 fi.ReSignal();
  3384.             }
  3385.         }
  3386.     }
  3387. }
  3388.  
  3389. //--------------------------------------------------------------------------------------------------
  3390. #pragma segment MASelCommand
  3391.  
  3392. pascal Boolean IsOpen(short itsID,
  3393.                       void*)
  3394. {
  3395.     DCtlHandle dceHnd;
  3396.  
  3397.     if ((itsID >= 0) && (itsID < GetUnitNtryCnt()))
  3398.     {
  3399.         dceHnd = (*GetUTableBase())[itsID];
  3400.         return ((dceHnd) && ((((*dceHnd)->dCtlFlags) & 0x0400) != 0));
  3401.     }
  3402.     else
  3403.         return FALSE;
  3404. }
  3405.  
  3406.  
  3407. pascal void TApplication::OpenDeskAccessory(const Str255& deskAccName)
  3408. {
  3409.     short aRefNum;
  3410.     Handle drvrH;
  3411.     short theID;
  3412.     ResType theType;
  3413.     Str255 theName;
  3414.     Boolean oldPerm;
  3415.     Boolean ourHeap;
  3416.     FailInfo fi;
  3417.     GrafPtr savedPort;
  3418.  
  3419.     VOLATILE(aRefNum);
  3420.  
  3421.     // then go ahead and open it; it's in a separate process
  3422.     if (qNeedsProcessMgr || gConfiguration.hasProcessMgr)
  3423.     {
  3424.         GetPort(savedPort);
  3425.         aRefNum = OpenDeskAcc(deskAccName);
  3426.         SetPort(savedPort);
  3427.     }
  3428.     else
  3429.     {
  3430.         if (fi.Try())
  3431.         {
  3432.             aRefNum = 0;                        // Make sure failure handler works. 
  3433.  
  3434.             // Attempt to load the DA into memory.  If 'deskAccName' refers to another app 
  3435.             // rather than a real desk acc, then GetNamedResource returns a faked up handle 
  3436.             // courtesy of MultiFinder™. We open the DA with permanent allocation so as to 
  3437.             // ensure that we don't take space from our code segments.                       
  3438.  
  3439.             oldPerm = PermAllocation(TRUE);
  3440.             drvrH = GetNamedResource('DRVR', deskAccName);
  3441.             PermAllocation(oldPerm);
  3442.             FailNILResource(drvrH);                // Either there wasn't enough memory 
  3443.             // â€¦to load the DA, or something is 
  3444.             // â€¦seriously wrong. 
  3445.  
  3446.             // At this point if we are really opening a DA we know it fits in memory.  
  3447.  
  3448.             GetResInfo(drvrH, theID, theType, theName);// If it's a not a real DA then this 
  3449.             // will generate a ResError.   
  3450.             
  3451.             // Find out which zone it lives in, or if option key is down.
  3452.             ourHeap = ((HandleZone(drvrH) == ApplicZone()) || IsOptionKeyDown());
  3453.  
  3454.             if ((ResError() != noErr) ||        // If it's a MultiFinder fake DA, 
  3455.                 IsOpen(theID, this) ||            // â€¦or if the DA is already open, 
  3456.                 (!ourHeap))                        // â€¦or if it's not going in our heap 
  3457.             {
  3458.                 oldPerm = PermAllocation(TRUE);    // In case we guess wrong 
  3459.                 GetPort(savedPort);
  3460.                 aRefNum = OpenDeskAcc(deskAccName);// â€¦then go ahead and open it. 
  3461.                 SetPort(savedPort);
  3462.                 PermAllocation(oldPerm); 
  3463.             }
  3464.             else
  3465.             {
  3466.                 // If we get this far, we know we have a real DA and it's going into our     
  3467.                 // heap.  Open it, but them make sure we have enough memory to continue 
  3468.                 // running.    
  3469.  
  3470.                 FailSpaceIsLow();                // In case we're already low on mem. 
  3471.  
  3472.                 oldPerm = PermAllocation(TRUE);    // If the pig wants to wallow 
  3473.                 GetPort(savedPort);
  3474.                 aRefNum = OpenDeskAcc(deskAccName);// Use temporary allocation. 
  3475.                 SetPort(savedPort);
  3476.                 PermAllocation(oldPerm); 
  3477.  
  3478.                 FailSpaceIsLow();                // Fail if not enough memory left. 
  3479.                 FailNIL(*drvrH);                // â€¦or if the driver was purged to 
  3480.                 // â€¦satisfy a code space requirement.
  3481.             }
  3482.             fi.Success();
  3483.         }
  3484.         else    // Recover
  3485.         {
  3486.             if (aRefNum != 0)
  3487.                 CloseDeskAcc(aRefNum);
  3488.  
  3489.             if (fi.message == 0)
  3490.             {
  3491.                 gErrorParm3 = deskAccName;
  3492.                 // Get rid of leading null character 
  3493.                 if (gErrorParm3[1] == 0)
  3494.                     gErrorParm3.Delete(1, 1);
  3495.             }
  3496.  
  3497.             FailNewMessage(fi.error, fi.message, msgOpenFailed);
  3498.             fi.ReSignal();
  3499.         }
  3500.     }
  3501. }
  3502.  
  3503. //--------------------------------------------------------------------------------------------------
  3504. #pragma segment MAOpen
  3505.  
  3506. pascal void TApplication::OpenNew(CmdNumber itsCmdNumber)
  3507. {
  3508.     TDocument* aDocument = NULL;
  3509.     TFile* aFile = NULL;
  3510.     Str255 newTitle;
  3511.     TWindow* aWindow;
  3512.     FailInfo fi;
  3513.  
  3514.     VOLATILE(aDocument);
  3515.     
  3516.     if (fi.Try())
  3517.     {
  3518.         aFile = this->DoMakeFile(itsCmdNumber);
  3519.  
  3520.         aDocument = this->DoMakeDocument(this->KindOfDocument(itsCmdNumber, aFile), aFile);
  3521.         aDocument->DoInitialState();
  3522.  
  3523.         aDocument->DoMakeViews(kForDisplay);
  3524.         aDocument->DoMakeWindows();
  3525.  
  3526.         aDocument->UntitledName(newTitle);
  3527.         // For MacApp 1.1, newTitle should be always != '' 
  3528.         if (!newTitle.IsEmpty())
  3529.             aDocument->SetTitle(newTitle);
  3530.         else if ((aDocument->fWindowList) && (aDocument->fWindowList->GetSize() > 0))
  3531.         // Grope, grope, grope 
  3532.         {
  3533.             aWindow = (TWindow *)(aDocument->fWindowList->First());
  3534.             aWindow->GetTitle(newTitle);
  3535.             newTitle = newTitle.Copy(aWindow->fPreDocname, newTitle.Length() - aWindow->fConstTitle);
  3536.             aFile->SetName(newTitle);
  3537.         }
  3538.  
  3539.         this->AddDocument(aDocument);
  3540.  
  3541.         FailSpaceIsLow();                        // Fail if document leaves us with no room 
  3542.  
  3543.         // Don't attempt to show the windows until we're sure we won't fail 
  3544.         aDocument->ShowWindows();
  3545.  
  3546.         fi.Success();
  3547.     }
  3548.     else    // Recover
  3549.     {
  3550.         aDocument = (TDocument *)FreeIfObject((TObject *)aDocument);
  3551.  
  3552.         FailNewMessage(fi.error, fi.message, msgNewFailed);
  3553.         fi.ReSignal();
  3554.     }
  3555. }
  3556.  
  3557. //--------------------------------------------------------------------------------------------------
  3558. #pragma segment MAOpen
  3559.  
  3560. pascal void TApplication::OpenOld(CmdNumber itsOpenCmd,
  3561.                                   TFile* aFile)
  3562. // Called for opening a document, given its name 
  3563. {
  3564.     TDocument* aDocument = NULL;
  3565.     TDocument* otherDoc;
  3566.     Size oldCodeReserve,  oldMemReserve;
  3567.     FailInfo fi;
  3568.  
  3569.     VOLATILE(aDocument);
  3570.     VOLATILE(oldCodeReserve);
  3571.     VOLATILE(oldMemReserve);
  3572.  
  3573.     if (fi.Try())
  3574.     {
  3575.         // Set reserve down a little to ensure that we can open existing documents 
  3576.         GetReserveSize(oldCodeReserve, oldMemReserve);
  3577.         SetReserveSize(oldCodeReserve, oldMemReserve / 2);
  3578.  
  3579.         otherDoc = this->AlreadyOpen(aFile);
  3580.         if (!otherDoc)
  3581.         {
  3582.             aDocument = this->DoMakeDocument(this->KindOfDocument(itsOpenCmd, aFile), aFile);
  3583.             aDocument->ReadDocument(kForDisplay);
  3584.             aDocument->DoMakeViews(kForDisplay);
  3585.             aDocument->DoMakeWindows();
  3586.     
  3587.             this->AddDocument(aDocument);
  3588.     
  3589.             FailSpaceIsLow();                        // Fail if the document leaves us with no memory
  3590.             
  3591.             // Set the reserve back to where it was 
  3592.             SetReserveSize(oldCodeReserve, oldMemReserve);
  3593.     
  3594.             // Don't attempt to show the windows until we're sure we won't fail 
  3595.             aDocument->ShowWindows();
  3596.         }
  3597.         else
  3598.         {
  3599.             otherDoc->OpenAgain(itsOpenCmd, aDocument);
  3600.             SetReserveSize(oldCodeReserve, oldMemReserve);
  3601.         }
  3602.         fi.Success();
  3603.     }
  3604.     else    // Recover
  3605.     {
  3606.         aDocument = (TDocument *)(FreeIfObject(aDocument));
  3607.  
  3608.         if (fi.message == 0)
  3609.             aFile->GetName((Str63 &)gErrorParm3);
  3610.         // Set the reserve back to where it was 
  3611.         SetReserveSize(oldCodeReserve, oldMemReserve);
  3612.         FailNewMessage(fi.error, fi.message, msgOpenFailed);
  3613.         fi.ReSignal();
  3614.     }
  3615. }
  3616.  
  3617. //--------------------------------------------------------------------------------------------------
  3618. #pragma segment MAApplicationRes
  3619.  
  3620. pascal void TApplication::ProcessEvent(TEvent* event)
  3621. {
  3622. #if qDebug
  3623.     MAName aMAName;
  3624. #endif
  3625.  
  3626.     if (qDebug && (event == NULL))
  3627.         ProgramBreak("NULL passed to TApplication::ProcessEvent");
  3628.     else if (qDebug && (!IsObject(event)))        // since it's possible to have passed in a freed undoable command allocated in a global
  3629.                                                 // variable (due to pilot error)
  3630.     {
  3631.         VerboseIsObject(event);
  3632.         ProgramBreak("bogus object passed to TApplication::ProcessEvent");
  3633.     }
  3634.     else
  3635.     {
  3636. #if qDebug
  3637.         if (gIntenseDebugging)
  3638.         {
  3639.             event->GetClassName(aMAName);
  3640.             fprintf(stderr, "The Event to process: %s\n", (char *) aMAName);
  3641.         }
  3642. #endif
  3643.  
  3644.     }
  3645.     if (event)
  3646.         event->Process();
  3647. }
  3648.  
  3649. //--------------------------------------------------------------------------------------------------
  3650. #pragma segment MAApplicationRes
  3651. pascal void TApplication::PerformCommand(TCommand* command)    // OVERRIDE
  3652. {
  3653.     FailInfo    fi;
  3654.     Boolean        saveCmd;
  3655.     VPoint        initialPt;
  3656. #if qDebug
  3657.     MAName        aMAName;
  3658. #endif
  3659.  
  3660.     short        aCmdNumber;
  3661.  
  3662.     VOLATILE(aCmdNumber);
  3663.     VOLATILE(command);
  3664.  
  3665.     if (qDebug && !command)
  3666.         ProgramBreak("NULL passed to TApplication.PerformCommand");
  3667.     else if (qDebug && (!IsObject(command)))        /*  since it's possible to have passed in a
  3668.                                                   freed undoable command allocated in a
  3669.                                                   global variable (due to pilot error) */
  3670.     {
  3671.         VerboseIsObject(command);
  3672.         ProgramBreak("bogus object passed to TApplication.PerformCommand");
  3673.     }
  3674.     else
  3675.     {
  3676. #if qDebugMsg
  3677.         if (gIntenseDebugging)
  3678.         {
  3679.             command->GetClassName(aMAName);
  3680.             fprintf(stderr, "The Command to perform: %s\n", (char *) aMAName);
  3681.         }
  3682. #endif
  3683.  
  3684.         if (command)
  3685.         {
  3686.  
  3687.             saveCmd = (command) && (command->fCausesChange || command->fCanUndo);
  3688.  
  3689.             if (saveCmd)
  3690.             {
  3691.                 this->CommitLastCommand();        // it frees fLastCommand. If the last (fCausesChange or fCanUndo) command sets
  3692.                                                 // fFreeOnCompletion to FALSE then we can
  3693.                                                 // execute the same undoable command any
  3694.                                                 // number of times. Non-Undoable commands
  3695.                                                 // don't get FREEd here but immediately
  3696.                                                 // after they're executed (that's
  3697.                                                 // performed not shot)
  3698.  
  3699.                 if (qDebug &&!IsObject(command))
  3700.                 {
  3701.                     VerboseIsObject(command);
  3702.                     ProgramBreak("You may not want to continue with a command that's been _FREED_!");
  3703.                 }
  3704.             }
  3705.  
  3706.             if (fi.Try())
  3707.             {
  3708.                 if (fEventLevel == 1)            // Don't unload segs if in nested event handling
  3709.                     UnloadAllSegments();
  3710.  
  3711.                 gClipboardMgr->fClipClaimed = FALSE;
  3712.  
  3713.                 command->DoIt();
  3714.                 fi.Success();
  3715.             }
  3716.             else    // Recover
  3717.             {
  3718.                 if (gClipboardMgr->fClipClaimed)
  3719.                 {
  3720.                     gClipboardMgr->SetClipView(gClipboardMgr->fClipUndoView);
  3721.                     gClipboardMgr->fClipUndoView = NULL;
  3722.                     // The newly-installed view needs to be freed also 
  3723.                     /* SwapClipViews;*/            /* Get original back there… !!! would be nice
  3724.                                                   but doesn't do right thing yet */
  3725.                 }
  3726.  
  3727.                 aCmdNumber = (short)(command->fID);
  3728.                 if (command->ShouldFreeOnCompletion())
  3729.                     command = (TCommand*)(FreeIfObject(command));
  3730.  
  3731.                 if (command == fLastCommand)
  3732.                     fLastCommand = NULL;        // make sure we clear our reference 
  3733.  
  3734.                 FailNewMessage(fi.error, fi.message, BuildMessage(aCmdNumber, msgCmdErr));
  3735.                 fi.ReSignal();
  3736.             }
  3737.             if (saveCmd)
  3738.             {
  3739.                 fLastCommand = command;
  3740.                 command->fCmdDone = TRUE;
  3741.             }
  3742.  
  3743.             // This is done after .DoIt, so .DoIt can change the fCausesChange flag 
  3744.             if ((command) && command->fCausesChange && (command->fChangedObject))
  3745.                 command->fChangedObject->Changed(command->GetChangeID(), command);/* Notify the proper object
  3746.                                                   that a change has occurred */
  3747.  
  3748.             if (!saveCmd && command->ShouldFreeOnCompletion())
  3749.                 command = (TCommand*)FreeIfObject(command);
  3750.         }
  3751.     }
  3752. }
  3753.  
  3754. //--------------------------------------------------------------------------------------------------
  3755. #pragma segment MAApplicationRes
  3756.  
  3757. pascal void TApplication::PollEvent(Boolean allowApplicationToSleep)
  3758. {
  3759.     FailInfo fi;
  3760.     TEvent* retrievedEvent;
  3761.     Boolean didAllowApplicationToSleep = fAllowApplicationToSleep;
  3762.  
  3763.     VOLATILE(didAllowApplicationToSleep);
  3764.  
  3765.     fAllowApplicationToSleep = allowApplicationToSleep;
  3766.  
  3767.     ++fEventLevel;
  3768.  
  3769. #if qDebugMsg
  3770.     if (this->GetTarget() == NULL)
  3771.         fprintf(stderr, "Serious Error!!! in TApplication.PollEvent: target == NULL\n");
  3772. #endif
  3773.  
  3774.     if (fi.Try())
  3775.     {
  3776.         retrievedEvent = this->RetrieveAnEvent();
  3777.         if (retrievedEvent)
  3778.             this->ProcessEvent(retrievedEvent);
  3779.             
  3780.         /* The desk scrap may have been changed by use of Cmd-X or Cmd-C in
  3781.           desk accessories. */
  3782.         if (fSysWindowActive)
  3783.         {
  3784.             gClipboardMgr->CheckDeskScrap();
  3785.             this->InvalidateFocus();
  3786.         }
  3787.  
  3788.         fi.Success();
  3789.         --fEventLevel;
  3790.  
  3791.         if (fEventLevel == 0)
  3792.             gInhibitNestedHandling = FALSE;        // All clear 
  3793.     }
  3794.     else    // Recover
  3795.     {
  3796. #if qDebugMsg
  3797.         fprintf(stderr, "\n");                    // add a blank line after all the messages from Failure
  3798. #endif
  3799.  
  3800.         fAllowApplicationToSleep = didAllowApplicationToSleep;
  3801.  
  3802.         --fEventLevel;
  3803.         if (fEventLevel == 0)
  3804.         {
  3805.             if (fi.error != noErr)
  3806.             {
  3807.                 UnloadAllSegments();
  3808.                 this->ShowError(fi.error, fi.message);
  3809.             }
  3810.  
  3811.             InvalidateMenus();
  3812.         }
  3813.     }
  3814.  
  3815.     fAllowApplicationToSleep = didAllowApplicationToSleep;
  3816. }
  3817.  
  3818. //--------------------------------------------------------------------------------------------------
  3819. #pragma segment MAApplicationRes
  3820.  
  3821. pascal void TApplication::PollToolboxEvent(Boolean allowApplicationToSleep)
  3822. {
  3823.     EventRecord theEvent;
  3824.     TToolboxEvent * event;
  3825.     long waitTicks;
  3826.     RgnHandle sleepRgn;
  3827.  
  3828.  
  3829.     if (EventAvail(fMainEventMask, theEvent))    // If any waiting Events (keystrokes, mousedowns) we won't be sleeping anyway
  3830.     {
  3831.         sleepRgn = NULL;
  3832.         waitTicks = 0;
  3833.     }
  3834.     else
  3835.     {
  3836.         this->SetupTheMenus();
  3837.         sleepRgn = this->GetSleepRgn();
  3838.         waitTicks = this->GetWaitTicks(allowApplicationToSleep);// calc last so it's most accurate 
  3839.     }
  3840.  
  3841.     HiliteMenu(0);                                // Cleanup any menu titles left hilited. Done here so titles stay hilited until
  3842.                                                 // synchronous actions are performed.
  3843.     event = this->GetEvent(fMainEventMask, waitTicks, sleepRgn);
  3844.     if (event)
  3845.     {
  3846.         /* GetEvent returned an event (work to do).    If we were idling before then we must
  3847.           keep the calls balanced with an IdleEnd to because we are no longer idling */
  3848.         if (fIdlePhase == idleContinue)
  3849.         {
  3850.             this->Idle(idleEnd);
  3851.             fIdlePhase = idleBegin;
  3852.         }
  3853.         this->PostAnEvent(event);
  3854.     }
  3855.     else                                        // Woke up with no event available. Truly idle
  3856.     {
  3857.         this->Idle(fIdlePhase);
  3858.         fIdlePhase = idleContinue;
  3859.     }
  3860.  
  3861.     if (qDebug)
  3862.         gErrorParm3 = "?????";                    // to prevent anyone from using old values 
  3863. }
  3864.  
  3865. //--------------------------------------------------------------------------------------------------
  3866. #pragma segment MAApplicationRes
  3867.  
  3868. pascal void TApplication::PostAnEvent(TEvent* event)    // Override
  3869. {
  3870.     Boolean oldObjectPerm;
  3871.  
  3872.     oldObjectPerm = AllocateObjectsFromPerm(FALSE);
  3873.     fEventList->Insert(event);                // inserts event ordered the list 
  3874.     AllocateObjectsFromPerm(oldObjectPerm);
  3875. }
  3876.  
  3877. //--------------------------------------------------------------------------------------------------
  3878. #pragma segment MAApplicationRes
  3879.  
  3880. pascal void TApplication::PostCommand(TCommand* command)    // Override
  3881. {
  3882.     ///!!! Left in for compatibility
  3883.     this->PostAnEvent(command);
  3884. }
  3885.  
  3886. //--------------------------------------------------------------------------------------------------
  3887. #pragma segment MAApplicationRes
  3888.  
  3889. pascal void TApplication::PostDoEvent(TEvent* event)
  3890. {
  3891.     Boolean perm;
  3892.  
  3893.     if (event && event->fAffectsMenus)
  3894.         InvalidateMenus();
  3895.  
  3896.     perm = PermAllocation(FALSE);
  3897. #if qDebug
  3898.     if (perm)
  3899.         ProgramBreak("The permanent flag was left TRUE.");
  3900. #endif
  3901.  
  3902.     // See if a system window has been activated or deactivated. 
  3903.     if (!(qNeedsProcessMgr || gConfiguration.hasProcessMgr) && (fSysWindowActive != this->IsDeskAccessory(FrontWindow())))
  3904.     {
  3905.         fSysWindowActive =!fSysWindowActive;
  3906.  
  3907.         if (fSysWindowActive)                    // deactivating to sys window 
  3908.         {
  3909.             this->AboutToLoseControl(TRUE);
  3910.             InvalidateMenuBar();
  3911.         }
  3912.         else                                    // coming back from sys window 
  3913.             this->RegainControl(TRUE);
  3914.     }
  3915.  
  3916.     if (event && (event->ShouldFreeOnCompletion())) //!!!RCR
  3917.         event = (TEvent *)FreeIfObject(event); 
  3918. }
  3919.  
  3920. //--------------------------------------------------------------------------------------------------
  3921. #pragma segment MAFinder
  3922.  
  3923. pascal Boolean TApplication::PrintDocument(TFile* aFile)
  3924. {
  3925.     TDocument* aDocument = NULL;
  3926.     FailInfo fi;
  3927.  
  3928.     VOLATILE(aDocument);
  3929.     
  3930.     if (fi.Try())
  3931.     {
  3932.         aDocument = this->DoMakeDocument(this->KindOfDocument(cFinderPrint, aFile), aFile);
  3933.         aDocument->ReadDocument(kForPrinting);
  3934.         aDocument->DoMakeViews(kForPrinting);
  3935.  
  3936.         // Note that if we are finder printing, this segment will be resident 
  3937.         UnloadAllSegments();
  3938.  
  3939.         gFinderPrintingProceed = TRUE;            // set in TStdPrintHandler::DoPrintCommand
  3940.         aDocument->HandleMenuCommand(cFinderPrint);
  3941.  
  3942.         UnloadAllSegments();
  3943.         fi.Success();
  3944.     }
  3945.     else    // Recover
  3946.     {
  3947.         aDocument = (TDocument *)FreeIfObject(aDocument);
  3948.         fi.ReSignal();
  3949.     }
  3950.     aDocument = (TDocument *)FreeIfObject(aDocument);
  3951.  
  3952.     UnloadAllSegments();
  3953.  
  3954.     return gFinderPrintingProceed;
  3955. }
  3956.  
  3957. //--------------------------------------------------------------------------------------------------
  3958. #pragma segment MAApplicationRes
  3959.  
  3960. pascal void TApplication::RegainControl(Boolean checkClipboard)
  3961. {
  3962.     CWMgrIterator iter;
  3963.  
  3964.     this->ActivateBusyCursor(TRUE);
  3965.  
  3966.     gClipboardMgr->RegainControl(checkClipboard);
  3967.  
  3968.     // Let all windows know that we're regaining control - e.g. so floaters can show themselves 
  3969.     for (WindowPtr aWinPtr = iter.FirstWMgrWindow(); iter.More(); aWinPtr = iter.NextWMgrWindow())
  3970.     {
  3971.         TWindow* aWindow = this->WMgrToWindow(aWinPtr);
  3972.     
  3973.         if (aWindow)
  3974.             aWindow->RegainControl();
  3975.     }
  3976. }
  3977.  
  3978. //--------------------------------------------------------------------------------------------------
  3979. #pragma segment MAApplicationRes
  3980. // must be in the main segment 
  3981.  
  3982. pascal void TApplication::Run(void)
  3983. {
  3984.     UnloadAllSegments();
  3985.     FailSpaceIsLow();                            // make sure we have enough memory to continue
  3986.     gInitialized = TRUE;                        // was set FALSE in InitToolBox 
  3987.  
  3988.     gClipboardMgr->Launch();                    // Launch after segments are unloaded since reading the scrap may be piggy
  3989.     // I know this looks funny but this does cover the case where we are built for 
  3990.     // system 6.0 but are running on system 7.0.  In that case we still don't want 
  3991.     // to HandleFinderRequest.  However if we are built for system 7.0 then this 
  3992.     // code will be conditionally compiled out 
  3993.     if (!gConfiguration.hasAppleEventMgr)
  3994.     {
  3995.         UnloadAllSegments();
  3996.         this->HandleFinderRequest();
  3997.     }
  3998.  
  3999.     UnloadAllSegments();
  4000.     fEventLevel = 0;                            // Indicate outermost level 
  4001.     this->MainEventLoop();                        // runs until a quit command 
  4002.  
  4003.     this->AboutToLoseControl(TRUE);
  4004.  
  4005. #if qDebug
  4006.     /* See if previous max. resource usage has been exceeded by the termi-
  4007.       nation code and resources. */
  4008.     CheckRsrcUsage();
  4009. #endif
  4010.  
  4011.     // We must call CleanupMacApp here; if we wait to fall thru to the end of the main
  4012.     // program, A5 has been invalidated and we can't refer to any globals.
  4013.     CleanupMacApp();
  4014. }
  4015.  
  4016. //--------------------------------------------------------------------------------------------------
  4017. #pragma segment MAApplicationRes
  4018.  
  4019. pascal void TApplication::SelectWMgrWindow(WindowPtr aWMgrWindow)
  4020. {
  4021.     SelectWindow(aWMgrWindow);                    // Simply call the toolbox to select it. 
  4022.     fLastClickPart = inDesk;                    // Make sure previous mouse clicks are not 
  4023.                                                 // are not considered part of a multi-click. 
  4024. }
  4025.  
  4026. //--------------------------------------------------------------------------------------------------
  4027. #pragma segment MAApplicationRes
  4028.  
  4029. pascal void TApplication::SetTarget(TEvtHandler* newTarget)
  4030. {
  4031.     if (newTarget == NULL)
  4032.     {
  4033.         newTarget = this;
  4034. #if qDebug
  4035.         ProgramBreak("In TApplication.SetTarget…  you''re setting the global target to nil!");
  4036. #endif
  4037.     }
  4038.     
  4039.     if (newTarget != fTarget)
  4040.     {
  4041.         fTarget->ResignedApplicationTarget();
  4042.         fTarget = newTarget;
  4043.         fTarget->BecameApplicationTarget();
  4044.         this->InvalidateMouseRegions();
  4045.     }
  4046. }    
  4047.  
  4048. //--------------------------------------------------------------------------------------------------
  4049. #pragma segment MAApplicationRes
  4050.  
  4051. pascal void TApplication::SetUndoText(Boolean cmdDone,
  4052.                                       CmdNumber aCmdNumber)
  4053. {
  4054.     short newMenuState;
  4055.     Str255 undoName;
  4056.     Str255 cmdName;
  4057.     short preCmdName;
  4058.     short constChars;
  4059.  
  4060.     if ((fUndoState != cmdDone) || (fUndoCmd != aCmdNumber))
  4061.     {
  4062.         if (aCmdNumber == cCantUndo)
  4063.             newMenuState = bzCantUndo;
  4064.         else if (cmdDone)
  4065.             newMenuState = bzUndo;
  4066.         else
  4067.             newMenuState = bzRedo;
  4068.  
  4069.         GetIndString(undoName, kIDBuzzString, newMenuState);
  4070.         if (ParseTitleTemplate(undoName, preCmdName, constChars))
  4071.         {
  4072.             if ((aCmdNumber == cNoCommand) || (aCmdNumber == cCantUndo))
  4073.                 cmdName = "";
  4074.             else
  4075.                 CmdToName(aCmdNumber, cmdName);
  4076.             SubstituteInTitle(undoName, cmdName, preCmdName, constChars);
  4077.         }
  4078.  
  4079.         SetCmdName(cUndo, undoName);
  4080.  
  4081.         fUndoState = cmdDone;
  4082.         fUndoCmd = aCmdNumber;
  4083.     }
  4084. }
  4085.  
  4086. //--------------------------------------------------------------------------------------------------
  4087. #pragma segment MAApplicationRes
  4088.  
  4089. class CSetupTheMenus
  4090. {
  4091.     // Fields
  4092.  
  4093.     TApplication* fApplication;
  4094.  
  4095. public:
  4096.  
  4097.     // Constructor
  4098.  
  4099.     CSetupTheMenus(TApplication* theApplication) :
  4100.         fApplication(theApplication)
  4101.     {
  4102.     }
  4103.  
  4104.     // Method
  4105.  
  4106.     pascal void DoSetup(void);
  4107. };
  4108.  
  4109. //--------------------------------------------------------------------------------------------------
  4110. #pragma segment MAApplicationRes
  4111.  
  4112. pascal void CSetupTheMenus::DoSetup(void)
  4113. {
  4114.     Boolean undoState;
  4115.     CmdNumber undoCmd;
  4116.     TWindow * aWindow = NULL;
  4117.     TCommand * lastCommand = NULL;
  4118. #if qInspector
  4119.     Boolean lowSpace;
  4120. #endif
  4121.  
  4122.     if (!fApplication->InModalMenuState())
  4123.     {
  4124. #if qInspector
  4125.         lowSpace = MemSpaceIsLow();
  4126. #endif
  4127.  
  4128.         aWindow = fApplication->GetActiveWindow();
  4129.  
  4130.         //!!!RCR
  4131.         fApplication->GetTarget()->HandleSetupMenus();// Setup menus relevent to target chain 
  4132.  
  4133.         // Set up the menu commands that are not dependent on the target chain… 
  4134.  
  4135.         undoState = kShowCantUndo;                // Set the Undo menu defaults. 
  4136.         undoCmd = cCantUndo;
  4137.         if (fApplication->fSysWindowActive)
  4138.         {
  4139.             undoState = kShowUndo;
  4140.             undoCmd = cNoCommand;
  4141.             Enable(cUndo, TRUE);
  4142.             Enable(cCut, TRUE);
  4143.             Enable(cCopy, TRUE);
  4144.             Enable(cPaste, TRUE);
  4145.             Enable(cClear, TRUE);
  4146.         }
  4147.         else
  4148.         {
  4149.             lastCommand = fApplication->GetTarget()->GetLastCommand();
  4150.             if (lastCommand)
  4151.                 if (lastCommand->fCanUndo)
  4152.                 {
  4153.                     if (lastCommand->fCmdDone)
  4154.                         undoState = kShowUndo;
  4155.                     else
  4156.                         undoState = kShowRedo;
  4157.                     undoCmd = lastCommand->fID;
  4158.  
  4159.                     /* Enable Undo only if the last command was not document-specific
  4160.                       or the document changed is the current document. */
  4161.                     /*            Enable(cUndo, (lastCommand->fChangedDocument == NULL) || ((aWindow) &&
  4162.                       (lastCommand->fChangedDocument == aWindow->fDocument)));*/
  4163.                     //!!!MEB
  4164.                     Enable(cUndo, (!(lastCommand->fChangedObject && (lastCommand->fChangedObject->IsMemberClass(GetClassIDFromName("TDocument"))))) || ((aWindow) && (lastCommand->fChangedObject == aWindow->fDocument)));
  4165.                 }
  4166.         }
  4167.         fApplication->SetUndoText(undoState, undoCmd);
  4168.  
  4169.         /*!!! we should really just make a call to the debugger/inspector here and give
  4170.           them a shot at setting these up instead */
  4171. #if qDebug
  4172.         EnableCheck(cExperimenting, TRUE, gExperimenting);
  4173.         EnableCheck(cReportEvt, TRUE, gReportEvt);
  4174.         EnableCheck(cDebugPrinting, TRUE, gDebugPrinting);
  4175.         EnableCheck(cReportMenuChoices, TRUE, gReportMenuChoices);
  4176.         EnableCheck(cIntenseDebugging, TRUE, gIntenseDebugging);
  4177.         Enable(cEnterMacAppDebugger, TRUE);
  4178.  
  4179.         if (aWindow)
  4180.         {
  4181.             Enable(cModalToggle, TRUE);
  4182.             SetMenuState(cModalToggle, kDebugBuzzStrings, bzMakeModal, bzMakeModeless, aWindow->fIsModal);
  4183.             Enable(cRefreshFrontWindow, TRUE);
  4184.             Enable(cDoFirstClick, TRUE);
  4185.             SetMenuState(cDoFirstClick, kDebugBuzzStrings, bzDoFirstClick, bzDontDoFirstClick, aWindow->fDoFirstClick);
  4186.         }
  4187.  
  4188.         // System Justification 
  4189.         Enable(cSetSysJust, TRUE);
  4190.         SetMenuState(cSetSysJust, kDebugBuzzStrings, bzSetRightSysJust, bzSetLeftSysJust, GetActualJustification(teFlushDefault) != teFlushLeft);
  4191.  
  4192.         EnableCheck(cTraceSetupMenus, TRUE, gTraceSetupMenus);
  4193.         EnableCheck(cTraceIdle, TRUE, gTraceIdle);
  4194.  
  4195.         Enable(cDebugWind, TRUE);
  4196. #endif
  4197.  
  4198. #if qInspector
  4199.         Enable(cNewInspectorWindow, !lowSpace);
  4200. #endif
  4201.  
  4202.     }
  4203.  
  4204.     MenuHandle appleMenu = MAGetMenu(mApple);
  4205.     if (((*appleMenu)->enableFlags & 1) == fApplication->InModalState())
  4206.     {
  4207.         (*appleMenu)->enableFlags = ((*appleMenu)->enableFlags ^ 1);
  4208.         InvalidateMenuBar();
  4209.     }
  4210.  
  4211. }
  4212.  
  4213. //--------------------------------------------------------------------------------------------------
  4214. #pragma segment MAApplicationRes
  4215.  
  4216. pascal void TApplication::SetupTheMenus(void)
  4217. {
  4218.     CSetupTheMenus aCSetupTheMenus(this);
  4219.  
  4220.     if (this->IsFrontProcess() && (MenusHavePendingUpdate() || MenuBarHasPendingUpdate()))
  4221.         PerformMenuSetup((DoToVoidType) & CSetupTheMenus::DoSetup, &aCSetupTheMenus);
  4222. }                                                /*    SetupTheMenus    */
  4223.  
  4224. //--------------------------------------------------------------------------------------------------
  4225. #pragma segment MAOpen
  4226.  
  4227. pascal void TApplication::SFGetParms(CmdNumber,
  4228.                                      ProcPtr& fileFilter,
  4229.                                      TypeListHandle typeList,
  4230.                                      short& dlgID,
  4231.                                      Point& where,
  4232.                                      ProcPtr& dlgHook,
  4233.                                      ProcPtr& modalFilter,
  4234.                                      Ptr& activeList,
  4235.                                      ProcPtr& activateProc,
  4236.                                      Ptr yourDataPtr)
  4237. {
  4238.     DialogTHndl dlogTemplate;
  4239.     Rect dialogRect;
  4240.  
  4241.  
  4242.     if (qNeedsAliasMgr || gConfiguration.hasAliasMgr)
  4243.     {
  4244.         dlgID = sfGetDialogID;
  4245.         where = Point(-1,-1);
  4246.     }
  4247.     else
  4248.     {
  4249.         dlgID = getDlgID;                        // getDlgID defined by Standard File 
  4250.         dlogTemplate = (DialogTHndl)(GetResource('DLOG', dlgID));
  4251.         if (dlogTemplate)
  4252.         {
  4253.             dialogRect = (*dlogTemplate)->boundsRect;
  4254.             CenterRectOnScreen(dialogRect, TRUE, TRUE, TRUE);
  4255.             where = dialogRect[topLeft];
  4256.         }
  4257.         else
  4258.             where = Point(100,100);
  4259.     }
  4260.  
  4261.     SetHandleSize((Handle)typeList, 4);
  4262.     FailMemError();
  4263.     (**typeList)[0] = fMainFileType;
  4264.  
  4265.     fileFilter = NULL;
  4266.     dlgHook = NULL;
  4267.     modalFilter = NULL;
  4268.     activeList = NULL;
  4269.     activateProc = NULL;
  4270.     yourDataPtr = NULL;
  4271. }                                                /*    SFGetParms    */
  4272.  
  4273. //--------------------------------------------------------------------------------------------------
  4274. #pragma segment MAError
  4275.  
  4276. pascal void TApplication::ShowError(OSErr error,
  4277.                                     long message)
  4278. {
  4279.     ErrorAlert(error, message);
  4280. }                                                /*    ShowError    */
  4281.  
  4282. //--------------------------------------------------------------------------------------------------
  4283. #pragma segment MAApplicationRes
  4284.  
  4285. pascal void TApplication::SpaceIsLow(void)
  4286. {
  4287.     long now;
  4288.  
  4289.  
  4290.     if (fEventLevel == 1)                        /* Don't unload segs if nested event
  4291.                                                   handling*/
  4292.         UnloadAllSegments();
  4293.  
  4294.     // Show 'space is low' alert only after ever fLowSpaceInterval ticks. 
  4295.     if ((fLowSpaceInterval > 0) && this->IsFrontProcess())
  4296.     {
  4297.         now = TickCount();
  4298.         if (now > fNextSpaceMsg)
  4299.         {
  4300.             gInhibitNestedHandling = TRUE;        // Don't tell em again from the alert 
  4301.             StdAlert(phSpaceIsLow);
  4302.             fNextSpaceMsg = now + fLowSpaceInterval;
  4303.         }
  4304.     }
  4305. }                                                /*    SpaceIsLow    */
  4306.  
  4307. //--------------------------------------------------------------------------------------------------
  4308. #pragma segment MAApplicationRes
  4309.  
  4310. pascal void TApplication::DoSetCursor(Point globalMouse,
  4311.                                         RgnHandle cursorRgn)
  4312. {
  4313.     this->GetDefaultCursorRgn(globalMouse, cursorRgn);
  4314.     SetCursor(qd.arrow);
  4315. }
  4316.  
  4317. //--------------------------------------------------------------------------------------------------
  4318. #pragma segment MAApplicationRes
  4319.  
  4320. pascal TView* TApplication::HandleCursor(Point globalMouse,
  4321.                                          RgnHandle cursorRgn)
  4322. {
  4323.     WindowPtr aWMgrWindow;
  4324.     TWindow * cursorWindow;
  4325.     TView * cursorView;
  4326.  
  4327.     if (FindWindow(globalMouse, aWMgrWindow) == inContent)
  4328.     {
  4329.         cursorWindow = this->WMgrToWindow(aWMgrWindow);
  4330.         if ((cursorWindow) && cursorWindow->HandlesCursor())
  4331.         {
  4332.             VPoint windowVPt(globalMouse);
  4333.             cursorWindow->SuperToLocal(windowVPt);
  4334.             cursorView = cursorWindow->HandleCursor(windowVPt, fCursorRgn);
  4335.             
  4336.             // Convert cursor region from view coords to global coords 
  4337.             if ((cursorView) && !EmptyRgn(cursorRgn))
  4338.                 {
  4339.                 VPoint viewVPt = gZeroVPt;
  4340.                 cursorView->LocalToWindow(viewVPt);
  4341.                 cursorWindow->LocalToSuper(viewVPt);
  4342.                 OffsetRgn(cursorRgn, (short) viewVPt.h, (short) viewVPt.v);
  4343.                 }
  4344.             return cursorView;
  4345.         }
  4346.     }
  4347.     else
  4348.         return NULL;
  4349. }
  4350.  
  4351. //--------------------------------------------------------------------------------------------------
  4352. #pragma segment MAApplicationRes
  4353.  
  4354. pascal void TApplication::TrackCursor(Point globalMouse)
  4355. {
  4356.     TView * cursorView;
  4357.  
  4358. #if qDebugMsg
  4359.     if (PtInRgn(globalMouse, fCursorRgn))
  4360.     {
  4361.  
  4362.         if (gIntenseDebugging && gTraceIdle)
  4363.             fprintf(stderr, "cursor is in cursor region\n");
  4364.  
  4365.     }
  4366. #endif
  4367.  
  4368.     this->InvalidateCursorRgn();
  4369.  
  4370.     /* Find out if the cursor is in a window which handles the cursor,
  4371.       and if so, call HandleCursor to find the view which claimed the cursor, and the region
  4372.       it computed. */
  4373.  
  4374.     cursorView = this->HandleCursor(globalMouse,fCursorRgn);
  4375.     
  4376.     if (EmptyRgn(fCursorRgn))
  4377.         this->DoSetCursor(globalMouse,fCursorRgn);
  4378.  
  4379.     // Make sure the cursorpoint is included 
  4380.     PtAndRgn(globalMouse, fCursorRgn);
  4381.  
  4382. #if qDebugMsg
  4383.     if (gIntenseDebugging && gTraceIdle)
  4384.         if (fCursorRgn == NULL)
  4385.             fprintf(stderr, "fCursorRgn is NULL\n");
  4386.         else
  4387.         {
  4388.             //!!! These lines cause the Whoops check below to return true. Writeln seems to zap the region. 
  4389.             /*
  4390.               HLock((Handle)fCursorRgn);
  4391.               WrLblRect('fCursorRgn', (*fCursorRgn)->rgnBBox);
  4392.               fprintf(stderr, "\n");
  4393.               HUnlock((Handle)fCursorRgn);
  4394.             */
  4395.  
  4396.         }
  4397. #endif
  4398.  
  4399.     if (qDebug && gIntenseDebugging &&!PtInRgn(globalMouse, fCursorRgn))
  4400.     {
  4401.         fprintf(stderr, "Whoops, cursor region was not correctly calculated.\n");
  4402.         fprintf(stderr, "global cursor = ", (char *) globalMouse);
  4403.         fprintf(stderr, "  (*fCursorRgn)->rgnBBox = ", (char *) (*fCursorRgn)->rgnBBox);
  4404.         fprintf(stderr, "\n");
  4405.         ProgramBreak("The cursor is not in the cursor region at end of TApplication.TrackCursor!");
  4406.     }
  4407. }                                                /*    TrackCursor    */
  4408.  
  4409. //--------------------------------------------------------------------------------------------------
  4410. #pragma segment MAApplicationRes
  4411.  
  4412. pascal void TApplication::DoShowHelp(Point globalMouse,
  4413.                                         RgnHandle helpRgn)
  4414. {
  4415.     if (HMIsBalloon())
  4416.     {
  4417.         OSErr err = HMRemoveBalloon();
  4418.         if (err != hmNoBalloonUp)
  4419.             FailOSErr(err);
  4420.     }
  4421.     this->GetDefaultHelpRgn(globalMouse, helpRgn);
  4422. }
  4423.  
  4424. //--------------------------------------------------------------------------------------------------
  4425. #pragma segment MAApplicationRes
  4426.  
  4427. pascal TView* TApplication::HandleHelp(Point globalMouse, 
  4428.                                         RgnHandle helpRgn)
  4429. {
  4430.     WindowPtr     aWMgrWindow;
  4431.     TWindow*     helpWindow;
  4432.     TView*         helpView;
  4433.     VPoint         windowVPt;
  4434.     Rect         windowBounds;
  4435.  
  4436.     if (FindWindow(globalMouse, aWMgrWindow) == inContent)
  4437.     {
  4438.         helpWindow = this->WMgrToWindow(aWMgrWindow);
  4439.         if ((helpWindow) && helpWindow->HandlesHelp())
  4440.         {
  4441.             VPoint windowVPt(globalMouse);
  4442.             helpWindow->SuperToLocal(windowVPt);
  4443.             helpView = helpWindow->HandleHelp(windowVPt, helpRgn);
  4444.             
  4445.             if ((helpView) && !EmptyRgn(helpRgn))
  4446.             {
  4447.                 VPoint viewVPt = gZeroVPt;
  4448.                 helpView->LocalToWindow(viewVPt);
  4449.                 helpWindow->LocalToSuper(viewVPt);
  4450.                 OffsetRgn(helpRgn, (short) viewVPt.h, (short) viewVPt.v);
  4451.  
  4452.             }
  4453.             return helpView;
  4454.         }
  4455.     }
  4456.     else
  4457.         return NULL;
  4458. }
  4459.  
  4460. //--------------------------------------------------------------------------------------------------
  4461. #pragma segment MAApplicationRes
  4462.  
  4463. pascal void TApplication::TrackHelp(Point globalMouse)
  4464. {
  4465.     TView * helpView;
  4466.  
  4467. #if qDebugMsg
  4468.     if (PtInRgn(globalMouse, fHelpRgn))
  4469.     {
  4470.  
  4471.         if (gIntenseDebugging && gTraceIdle)
  4472.             fprintf(stderr, "cursor is in help region\n");
  4473.     }
  4474. #endif
  4475.  
  4476.     this->InvalidateHelpRgn();
  4477.  
  4478.     /* Find out if the cursor is in a window which handles help,
  4479.       and if so, call HandleHelp to find the view which claimed the cursor, and the region
  4480.       it computed. */
  4481.  
  4482.     helpView = this->HandleHelp(globalMouse,fHelpRgn);
  4483.  
  4484.     if (EmptyRgn(fHelpRgn))
  4485.         this->DoShowHelp(globalMouse, fHelpRgn);
  4486.  
  4487.     // Make sure the cursorpoint is included 
  4488.     PtAndRgn(globalMouse, fHelpRgn);
  4489.  
  4490. #if qDebugMsg
  4491.     if (gIntenseDebugging && gTraceIdle)
  4492.         if (fHelpRgn == NULL)
  4493.             fprintf(stderr, "fHelpRgn is NULL\n");
  4494.         else
  4495.         {
  4496.             /* !!! See comment in TrackCursor
  4497.               HLock((Handle)(fHelpRgn));
  4498.               WrLblRect('fHelpRgn', (*fHelpRgn)->rgnBBox);
  4499.               fprintf(stderr, "\n");
  4500.               HUnlock((Handle)(fHelpRgn));*/
  4501.         }
  4502. #endif
  4503.  
  4504.     if (qDebug && gIntenseDebugging &&!PtInRgn(globalMouse, fHelpRgn))
  4505.     {
  4506.         fprintf(stderr, "Whoops, help region was not correctly calculated.\n");
  4507.         fprintf(stderr, "global cursor = ", (char *) globalMouse);
  4508.         fprintf(stderr, "  (*fHelpRgn)->rgnBBox = ", (char *) (*fHelpRgn)->rgnBBox);
  4509.         fprintf(stderr, "\n");
  4510.         ProgramBreak("The cursor is not in the help region at end of TApplication.TrackHelp!");
  4511.     }
  4512.  
  4513. }                                                /*    TrackHelp    */
  4514.  
  4515. //--------------------------------------------------------------------------------------------------
  4516. #pragma segment MADoCommand
  4517.  
  4518. class CTrackerMgr
  4519. {
  4520.     // Fields
  4521.  
  4522. protected:
  4523.     TApplication* fApplication;
  4524.     Point hysteresis;
  4525.  
  4526.     TTracker* fTracker;
  4527.     TView* fView;
  4528.  
  4529.     VPoint fAnchorPoint;
  4530.     VPoint fPreviousPoint;
  4531.     VPoint fNextPoint;
  4532.  
  4533.     VPoint fLastAnchorPoint;
  4534.     VPoint fLastPreviousPoint;
  4535.     VPoint fLastNextPoint;
  4536.  
  4537.     Boolean fDeskTopTracking;
  4538.     CGrafPort fDeskTopTrackingPort;
  4539.     GrafPtr fSavedPort;
  4540.     TrackPhase fTrackPhase;
  4541.  
  4542. public:
  4543.  
  4544.     // Constructor
  4545.  
  4546.     CTrackerMgr(TApplication* theApplication,
  4547.                 const VPoint& theMouse,
  4548.                 Point theHysteresis,
  4549.                 TTracker* theTracker) :
  4550.  
  4551.         fApplication(theApplication),
  4552.         fAnchorPoint(theMouse),
  4553.         hysteresis(theHysteresis),
  4554.         fTracker(theTracker)
  4555.     {
  4556.         fView = NULL;
  4557.         fSavedPort = NULL;
  4558.  
  4559.         fDeskTopTracking = FALSE;
  4560.         fTrackPhase = trackBegin;
  4561.  
  4562.         fPreviousPoint = theMouse;
  4563.         fNextPoint = theMouse;
  4564.     }
  4565.  
  4566.     // Methods
  4567.  
  4568.     TTracker* DoTracking(void);
  4569.  
  4570.     void CleanUpFocus(void);
  4571.  
  4572.     void DoFocus(void);
  4573.  
  4574.     void InstallTracker(TTracker* newTracker);
  4575.  
  4576.     void FeedbackOnce(Boolean mouseDidMove,
  4577.                                 Boolean turnItOn);
  4578.  
  4579.     void ConstrainOnce(Boolean didMouseMove);
  4580.  
  4581.     void TrackOnce(Boolean didMouseMove);
  4582.  
  4583. };
  4584.  
  4585. //--------------------------------------------------------------------------------------------------
  4586. #pragma segment MADoCommand
  4587.  
  4588. void CTrackerMgr::CleanUpFocus(void)
  4589. {
  4590.     if (fDeskTopTracking)
  4591.     {
  4592.         if (qNeedsColorQD || gConfiguration.hasColorQD)
  4593.             CloseCPort(&fDeskTopTrackingPort);
  4594.         else
  4595.             ClosePort((GrafPtr) & fDeskTopTrackingPort);
  4596.         SetPort(fSavedPort);
  4597.         fDeskTopTracking = FALSE;
  4598.     }
  4599. }
  4600.  
  4601. //--------------------------------------------------------------------------------------------------
  4602. #pragma segment MADoCommand
  4603.  
  4604. void CTrackerMgr::DoFocus(void)
  4605. {
  4606.     if (fView)
  4607.     {
  4608.         if (fDeskTopTracking)
  4609.             CleanUpFocus();
  4610.  
  4611.         if (!fView->Focus())
  4612.             {
  4613. #if qDebug
  4614.             ProgramBreak("TApplication.TrackMouse: Unable to focus fView.");
  4615. #endif
  4616.             }
  4617.     }
  4618.     else
  4619.     {                                            // focus on the desktop 
  4620.         if (!fDeskTopTracking)
  4621.         {
  4622.             GetPort(fSavedPort);                // In case we exit still focusedOnDeskTop 
  4623.             if (qNeedsColorQD || gConfiguration.hasColorQD)
  4624.                 OpenCPort(&fDeskTopTrackingPort);
  4625.             else
  4626.                 OpenPort((GrafPtr) & fDeskTopTrackingPort);
  4627.             fDeskTopTracking = TRUE;
  4628.         }
  4629.  
  4630.         CopyRgn(GetGrayRgn(), fDeskTopTrackingPort.visRgn);
  4631.         fDeskTopTrackingPort.portRect = (*(fDeskTopTrackingPort.visRgn))->rgnBBox;
  4632.         fApplication->InvalidateFocus();
  4633.     }
  4634. }                                                /*    DoFocus    */
  4635.  
  4636. //--------------------------------------------------------------------------------------------------
  4637. #pragma segment MADoCommand
  4638.  
  4639. void CTrackerMgr::InstallTracker(TTracker* newTracker)
  4640. {
  4641.     fTracker = newTracker;
  4642.     if (fTracker)
  4643.     {
  4644.         fView = fTracker->fView;
  4645.         DoFocus();
  4646.     }
  4647. }
  4648.  
  4649. //--------------------------------------------------------------------------------------------------
  4650. #pragma segment MADoCommand
  4651.  
  4652. void CTrackerMgr::ConstrainOnce(Boolean didMouseMove)// ??? fold this into TrackOnce ??? 
  4653. {
  4654.     if (fTracker && fTracker->fViewConstrain && (fView))
  4655.     {
  4656.         VRect viewExtent;
  4657.  
  4658.         fView->GetExtent(viewExtent);
  4659.         fNextPoint.ConstrainTo(viewExtent);
  4660.     }
  4661.     if (fTracker && fTracker->fConstrainsMouse)
  4662.         fTracker->TrackConstrain(fTrackPhase, fAnchorPoint, fPreviousPoint, fNextPoint, didMouseMove);
  4663. }
  4664.  
  4665. //--------------------------------------------------------------------------------------------------
  4666. #pragma segment MADoCommand
  4667.  
  4668. void CTrackerMgr::FeedbackOnce(Boolean mouseDidMove,
  4669.                                 Boolean turnItOn)
  4670. {
  4671.     if (fTracker)
  4672.     {
  4673.         PenNormal();
  4674.         PenMode(patXor);
  4675.         if (turnItOn)
  4676.         {
  4677.             fTracker->TrackFeedback(fTrackPhase, fAnchorPoint, fPreviousPoint, fNextPoint, mouseDidMove, turnItOn);
  4678.             // save these to turn it off with
  4679.             fLastAnchorPoint = fAnchorPoint;
  4680.             fLastPreviousPoint = fPreviousPoint;
  4681.             fLastNextPoint = fNextPoint;
  4682.         }
  4683.         else
  4684.         {
  4685.             fTracker->TrackFeedback(fTrackPhase, fLastAnchorPoint, fLastPreviousPoint, fLastNextPoint, mouseDidMove, turnItOn);
  4686.         }
  4687.     }
  4688. }
  4689.  
  4690. //--------------------------------------------------------------------------------------------------
  4691. #pragma segment MADoCommand
  4692.  
  4693. void CTrackerMgr::TrackOnce(Boolean didMouseMove)
  4694. {
  4695. #if qDebug
  4696.     if (!fTracker)
  4697.         ProgramBreak("In TApplication.TrackMouse: fTracker == NULL");
  4698. #endif
  4699.  
  4700.     if (fTracker)
  4701.     {
  4702.         TTracker * newTracker = fTracker->TrackMouse(fTrackPhase, fAnchorPoint, fPreviousPoint, fNextPoint, didMouseMove);
  4703.         if (newTracker != fTracker)
  4704.         {
  4705.             fTracker = (TTracker *)(FreeIfObject(fTracker));
  4706.  
  4707.             InstallTracker(newTracker);
  4708.         }
  4709.         else if (newTracker && (newTracker->fView != fView))
  4710.             InstallTracker(newTracker);
  4711.     }
  4712. }
  4713.  
  4714. //--------------------------------------------------------------------------------------------------
  4715. #pragma segment MADoCommand
  4716.  
  4717. TTracker* CTrackerMgr::DoTracking(void)
  4718. {
  4719.  
  4720.     Boolean movedOnce = FALSE;
  4721.  
  4722.     this->InstallTracker(fTracker);
  4723.  
  4724.     this->ConstrainOnce(TRUE);
  4725.     fAnchorPoint = fNextPoint;
  4726.     fPreviousPoint = fNextPoint;                // in case Constrain changed the fNextPoint;
  4727.                                                 // guarantee that all 3 are the same on trackBegin
  4728.  
  4729.     this->TrackOnce(TRUE);
  4730.     fAnchorPoint = fNextPoint;
  4731.     fPreviousPoint = fNextPoint;                // in case TrackMouse changed the fNextPoint;
  4732.                                                 // guarantee that all 3 are the same on trackBegin
  4733.  
  4734.     this->FeedbackOnce(TRUE, TRUE);
  4735.  
  4736.     fTrackPhase = trackContinue;                // supply trackphase to all interested parties
  4737.     while (fTracker && !fTracker->IsDoneTracking())
  4738.     {
  4739.         Point theQDMouse;
  4740.  
  4741.         this->DoFocus();
  4742.         GetMouse(theQDMouse);
  4743.         if (fView)
  4744.             fView->QDToViewPt(theQDMouse, fNextPoint);
  4745.         else
  4746.             fNextPoint = theQDMouse;
  4747.  
  4748.         if (!movedOnce)
  4749.         {
  4750.             this->ConstrainOnce(fPreviousPoint != fNextPoint);/* ensure that we are playing on a level
  4751.                                                   field. */
  4752.             VPoint amtMoved = fNextPoint - fAnchorPoint;
  4753.             if ((abs((int)amtMoved.h) >= hysteresis.h) || (abs((int)amtMoved.v) >= hysteresis.v))
  4754.                 movedOnce = TRUE;
  4755.         }
  4756.  
  4757.         VPoint delta = gZeroVPt;
  4758.         if (movedOnce || fTracker->fTrackNonMovement)
  4759.         {
  4760.             // ??? Problems with this:
  4761.             //  delta might be non-zero but scrolling can't take place
  4762.             //  because it is pinned at the end of the view
  4763.             //  also might want some slop before scrolling
  4764.  
  4765.             TScroller* scroller = fTracker->fScroller;
  4766.             if (scroller && fView)
  4767.             {
  4768.                 // convert fNextPoint to scroller coordinates
  4769.                 VPoint mouseInScroller = fNextPoint;
  4770.                 fView->LocalToWindow(mouseInScroller);
  4771.                 scroller->WindowToLocal(mouseInScroller);
  4772.  
  4773.                 // AutoScroll if the point is outside of the scroller's extent
  4774.                 VRect autoScrollLimit;
  4775.                 scroller->GetExtent(autoScrollLimit);
  4776.                 if (!autoScrollLimit.Contains(mouseInScroller))
  4777.                 {
  4778.                     scroller->AutoScroll(mouseInScroller, delta);// Get the amount to autoscroll
  4779.                     fNextPoint += delta;
  4780.                 }
  4781.             }
  4782.  
  4783.             this->ConstrainOnce(fPreviousPoint != fNextPoint);
  4784.         }
  4785.  
  4786.         Boolean willScroll = delta != gZeroVPt;
  4787.         Boolean didMove = fPreviousPoint != fNextPoint;
  4788.  
  4789.         this->FeedbackOnce(didMove || willScroll, FALSE);
  4790.  
  4791.         if (willScroll)
  4792.         {
  4793.             fTracker->AutoScroll(delta);        // OK, now actually do the scrolling 
  4794.             if (fView)
  4795.                 fView->Update();                /* Keep synchronized. ScrollDraw only
  4796.                                                   invalidated */
  4797.             this->DoFocus();                    // the focus changed 
  4798.         }
  4799.  
  4800.         this->TrackOnce(didMove);                // ??? add || willScroll ??? 
  4801.         this->FeedbackOnce(didMove || willScroll, TRUE);
  4802.  
  4803.         fPreviousPoint = fNextPoint;
  4804.     }
  4805.  
  4806.     fTrackPhase = trackEnd;                        // supply trackphase to all interested parties
  4807.  
  4808.     this->DoFocus();
  4809.  
  4810.     EventRecord peekEvent;
  4811.  
  4812.     if (!movedOnce)
  4813.         fNextPoint = fPreviousPoint;            /* normally same as original mouse down; we
  4814.                                                   don't use fAnchorPoint in case someone has
  4815.                                                   changed that -- it is more likely that an
  4816.                                                   app would change fAnchorPoint than
  4817.                                                   fPreviousPoint */
  4818.  
  4819.     else if (OSEventAvail(mUpMask + mDownMask, peekEvent))
  4820.     {
  4821.         Point theQDMouse = peekEvent.where;
  4822.         if (fView)
  4823.         {
  4824.             GlobalToLocal(theQDMouse);
  4825.             fView->QDToViewPt(theQDMouse, fNextPoint);
  4826.         }
  4827.         else
  4828.             fNextPoint = theQDMouse;
  4829.         this->ConstrainOnce(TRUE);
  4830.     }
  4831.     // else we use the last known mouse position 
  4832.  
  4833.     this->FeedbackOnce(TRUE, FALSE);
  4834.     this->TrackOnce(TRUE);
  4835.  
  4836.     this->CleanUpFocus();
  4837.  
  4838.     return fTracker;
  4839. }
  4840.  
  4841. //--------------------------------------------------------------------------------------------------
  4842. #pragma segment MADoCommand
  4843.  
  4844. pascal TTracker* TApplication::TrackMouse(const VPoint& theMouse,
  4845.                                           Point hysteresis,
  4846.                                           TTracker* theCommand)
  4847. {
  4848.     CTrackerMgr aCTrackerMgr(this, theMouse, hysteresis, theCommand);
  4849.  
  4850.     return aCTrackerMgr.DoTracking();
  4851. }
  4852.  
  4853. //--------------------------------------------------------------------------------------------------
  4854. #pragma segment MAApplicationRes
  4855.  
  4856. pascal void TApplication::UpdateAllWindows(void)
  4857. {
  4858.     TToolboxEvent * event;
  4859.  
  4860.     ++fEventLevel;
  4861.     while(event = this->GetEvent(updateMask + activMask, 0, NULL))
  4862.         event->Process();
  4863.     --fEventLevel;
  4864. }
  4865.  
  4866. //--------------------------------------------------------------------------------------------------
  4867. #pragma segment MAApplicationRes
  4868.  
  4869. pascal TWindow* TApplication::WMgrToWindow(WindowPtr aWMgrWindow)
  4870. {
  4871.     /* Make an IsObject test too because some slimedog may have created a window in our
  4872.       world and the refcon wouldn't be an object.  Since this is the only place in
  4873.       MacApp that we get asked to do something to a ToolBox structure where we don't _know_
  4874.       that we created the structure we need to be especially careful here.  ??? Perhaps in the
  4875.       future we should use a dictionary to make the windowPtr to TWindow association for us. */
  4876.     if (aWMgrWindow && (qNeedsProcessMgr || gConfiguration.hasProcessMgr ||!this->IsDeskAccessory(aWMgrWindow))
  4877.         && IsObject((TObject *)GetWRefCon(aWMgrWindow)))
  4878.         return (TWindow *)(GetWRefCon(aWMgrWindow));
  4879.     else
  4880.         return NULL;
  4881. }
  4882.  
  4883. //--------------------------------------------------------------------------------------------------
  4884. #pragma segment MAOpen
  4885.  
  4886. pascal void TApplication::DoMakeViewServer(void)
  4887. {
  4888.     TViewServer* aViewServer = new TViewServer;
  4889.     aViewServer->IViewServer();                            // assigns the global reference
  4890. }
  4891.